﻿/* ============================================================
   JEWISH CHANGEMAKERS PORTAL — DESIGN SYSTEM
   Ported from the prototype <style> block (DESIGN.md is the contract).
   8px spacing system · navy = structure · teal = progress/action.
   ============================================================ */
:root{
  --navy:#16223d;          /* anchor / structure */
  --navy-deep:#0f1830;
  --navy-soft:#27365a;
  --teal:#16b8a6;          /* progress + action + success */
  --teal-deep:#0f9a8b;
  --teal-press:#0c8175;
  --teal-wash:rgba(22,184,166,.10);
  --amber:#27277C;         /* brand primary navy — attention / pending states */
  --amber-wash:rgba(39,39,124,.09);
  --rose:#f76d6d;          /* used sparingly, never as failure-shame */
  --rose-wash:#fdecec;
  --rose-deep:#a83232;     /* the same rose, readable as small text on the wash */
  --violet:#ec4e75;        /* brand coral-pink — community / secondary accents */
  --violet-wash:rgba(236,78,117,.09);
  --violet-deep:#a8274e;   /* the same pink, readable as small text on a wash */
  --amber-deep:#1a1a5c;    /* the same navy, readable as small text on a wash */
  --navy-veil:rgba(15,24,48,.45);   /* scrim over cover art (locked week, gated media) */

  --bg:#f6f8fb;            /* app canvas - light only */
  --surface:#ffffff;
  --surface-2:#f1f4f9;
  --surface-3:#e8edf5;
  --border:#e4e9f1;
  --border-strong:#d3dbe7;

  --text:#16223d;
  --text-2:#5a667d;
  --text-3:#8a94a8;
  --text-on-navy:#eaf0fb;
  --text-on-teal:#ffffff;

  --star:#f59e0b;          /* lit star — ratings only, never a UI accent */
  --star-deep:#b45309;     /* the same gold, readable as small text */

  --r-sm:8px; --r-md:14px; --r-lg:20px; --r-xl:28px; --r-pill:999px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:64px;
  --shadow-sm:0 1px 3px rgba(22,34,61,.06),0 1px 2px rgba(22,34,61,.04);
  --shadow-md:0 6px 20px rgba(22,34,61,.10);
  --shadow-lg:0 16px 40px rgba(22,34,61,.16);
  --ease:cubic-bezier(.22,.61,.36,1);

  /* Typefaces. Staff → Appearance swaps these two for a chosen pairing; the values here are the
     portal's original lettering and the fallback if no theme has ever been saved. */
  --font-head:'Outfit',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-body:'Outfit',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}
/* Everything above is the complete default palette, deliberately: the Appearance theme is emitted as a
   second :root block in the page head and restates only what it changes, so a portal with no saved
   theme — or one whose theme can't be read — still renders fully styled rather than unstyled. */

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:var(--font-body);
  background:var(--bg);
  color:var(--text);
  -webkit-font-smoothing:antialiased;
  line-height:1.5;
  overflow-x:hidden;
}
/* Headings carry the pairing's display face; everything else inherits the body face. A pairing where
   both halves are the same family (the default) simply makes this a no-op. */
h1,h2,h3,h4,h5,h6{font-family:var(--font-head)}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,textarea,select{font-family:inherit}
a{color:inherit;text-decoration:none}
.tnum{font-variant-numeric:tabular-nums}

/* ============================================================
   APP SHELL
   ============================================================ */
#app{min-height:100vh;padding-top:72px;padding-bottom:var(--s6)}   /* clear the fixed single-row top bar */
.view{max-width:1400px;margin:0 auto;padding:var(--s5) var(--s4)}
@media(min-width:900px){
  #app{padding-bottom:0;padding-top:124px}                          /* clear the two-row header */
  .view{padding:var(--s6) var(--s5)}
}

/* ---------- TOP NAV ---------- */
.topnav{
  display:block;position:fixed;top:0;left:0;right:0;z-index:40;
  background:rgba(255,255,255,.92);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--border);
}
.topnav-inner{max-width:1400px;margin:0 auto;height:64px;display:flex;align-items:center;
  gap:var(--s4);padding:0 var(--s5)}
.brand{display:flex;align-items:center;gap:var(--s2);font-weight:700;font-size:16px;letter-spacing:-.02em}
.brand .mark{width:30px;height:30px;border-radius:9px;background:linear-gradient(135deg,var(--navy),var(--teal));
  display:grid;place-items:center;color:#fff;font-weight:700;font-size:15px;flex:0 0 auto}
/* Staff-uploaded header logo — replaces the .mark. Capped well under the 64px bar so it keeps clear
   space above and below (matching the 30px mark's breathing room). */
.brand-logo{max-height:40px;width:auto;max-width:260px;object-fit:contain;display:block;flex:0 0 auto}

/* Hamburger — small screens only */
.navtoggle{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;
  margin-left:-6px;border:none;background:transparent;color:var(--navy);border-radius:var(--r-md);cursor:pointer}
.navtoggle:hover{background:var(--surface-2)}

/* Second bar with the nav links (desktop), left-aligned under the logo */
.topnav-sub{display:none;border-top:1px solid var(--border)}
.topnav-sub-inner{max-width:1400px;margin:0 auto;padding:var(--s2) var(--s5)}
/* Scrolls rather than squeezing. The staff set reached thirteen entries in 2026-08 (Interest, Coaches, Nominations,
   Reimbursements),
   which needs more track than the sub-bar has between its 900px breakpoint and about 1150px; without
   this the pills compress and their labels wrap inside them. */
.topnav .tabs{display:flex;gap:var(--s1);overflow-x:auto;scrollbar-width:none}
.topnav .tabs::-webkit-scrollbar{display:none}
.topnav .tab{
  padding:8px 14px;border-radius:var(--r-pill);font-size:14px;font-weight:500;color:var(--text-2);
  transition:background .15s var(--ease),color .15s var(--ease);position:relative;
  white-space:nowrap;flex-shrink:0;
}
.topnav .tab:hover{background:var(--surface-2);color:var(--text)}
.topnav .tab.active{background:var(--navy);color:#fff}
.topnav .tab .dot{position:absolute;top:6px;right:8px;width:7px;height:7px;border-radius:50%;
  background:var(--teal);box-shadow:0 0 0 2px #fff}
.topnav .spacer{flex:1}

@media(min-width:900px){
  .navtoggle{display:none}
  .topnav-sub{display:block}
}

/* ---------- NAV DRAWER (small screens) ---------- */
.navdrawer{position:fixed;inset:0;z-index:60;visibility:hidden}
body.nav-open .navdrawer{visibility:visible}
.navdrawer-backdrop{position:absolute;inset:0;background:rgba(22,34,61,.42);opacity:0;
  transition:opacity .2s var(--ease)}
body.nav-open .navdrawer-backdrop{opacity:1}
.navdrawer-panel{position:absolute;top:0;left:0;bottom:0;width:284px;max-width:84vw;
  background:var(--surface);box-shadow:0 12px 40px rgba(16,34,61,.22);
  transform:translateX(-100%);transition:transform .24s var(--ease);
  display:flex;flex-direction:column;padding:var(--s4);overflow-y:auto}
body.nav-open .navdrawer-panel{transform:translateX(0)}
.navdrawer-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--s4)}
.navdrawer-close{border:none;background:transparent;font-size:18px;line-height:1;color:var(--text-2);
  width:36px;height:36px;border-radius:var(--r-md);cursor:pointer}
.navdrawer-close:hover{background:var(--surface-2)}
.tabs-vertical{display:flex;flex-direction:column;gap:4px}
.navdrawer .tab{display:block;padding:11px 14px;border-radius:var(--r-md);font-size:15px;font-weight:500;
  color:var(--text-2);position:relative;transition:background .15s var(--ease),color .15s var(--ease)}
.navdrawer .tab:hover{background:var(--surface-2);color:var(--text)}
.navdrawer .tab.active{background:var(--navy);color:#fff}
.navdrawer .tab .dot{position:absolute;top:14px;right:12px;width:7px;height:7px;border-radius:50%;background:var(--teal)}
@media(min-width:900px){.navdrawer{display:none}}

/* ---------- BOTTOM TAB BAR (mobile only) ---------- */
.tabbar{
  position:fixed;bottom:0;left:0;right:0;z-index:40;background:rgba(255,255,255,.92);
  backdrop-filter:blur(14px);border-top:1px solid var(--border);
  display:flex;justify-content:space-around;padding:8px 4px calc(8px + env(safe-area-inset-bottom));
}
.tabbar a{display:flex;flex-direction:column;align-items:center;gap:3px;flex:1;
  padding:6px 0;border-radius:var(--r-md);color:var(--text-3);font-size:10.5px;font-weight:600;
  transition:color .15s var(--ease);position:relative}
.tabbar a .ic{width:24px;height:24px;display:grid;place-items:center;transition:transform .2s var(--ease)}
.tabbar a.active{color:var(--teal-deep)}
.tabbar a.active .ic{transform:translateY(-2px)}
.tabbar a .dot{position:absolute;top:4px;right:calc(50% - 16px);width:7px;height:7px;border-radius:50%;
  background:var(--teal);box-shadow:0 0 0 2px #fff}
@media(min-width:900px){.tabbar{display:none}}

/* ============================================================
   PRIMITIVES
   ============================================================ */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);transition:transform .18s var(--ease),box-shadow .18s var(--ease),border-color .18s var(--ease)}
.card.lift:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);border-color:var(--border-strong)}
.card-pad{padding:var(--s5)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:600;font-size:14px;
  border-radius:var(--r-pill);padding:11px 22px;transition:transform .12s var(--ease),background .15s var(--ease),box-shadow .15s var(--ease);
  white-space:nowrap}
.btn:active{transform:scale(.96)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn-primary{background:var(--teal);color:var(--text-on-teal);box-shadow:0 4px 14px rgba(22,184,166,.32)}
.btn-primary:hover{background:var(--teal-deep)}
.btn-primary:active{background:var(--teal-press)}
.btn-navy{background:var(--navy);color:#fff}
.btn-navy:hover{background:var(--navy-soft)}
.btn-ghost{background:var(--surface-2);color:var(--text)}
.btn-ghost:hover{background:var(--surface-3)}
.btn-outline{background:transparent;border:1.5px solid var(--border-strong);color:var(--text)}
.btn-outline:hover{background:var(--surface-2)}
.btn-sm{padding:8px 16px;font-size:13px}
.btn-block{display:flex;width:100%}

.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:var(--r-pill);
  font-size:12px;font-weight:600;line-height:1.4}
.chip-teal{background:var(--teal-wash);color:var(--teal-deep)}
.chip-navy{background:var(--surface-3);color:var(--navy)}
.chip-amber{background:var(--amber-wash);color:#1a1a5c}
.chip-violet{background:var(--violet-wash);color:#a8274e}
.chip-rose{background:var(--rose-wash);color:#d84a4a}
/* leading status dot — inherits the chip's colour unless the caller overrides it */
.chip .dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0}
.chip .d{width:7px;height:7px;border-radius:50%;background:currentColor}

.eyebrow{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}
h1.page{font-size:26px;font-weight:700;letter-spacing:-.02em;margin:2px 0 4px}
.sub{color:var(--text-2);font-size:15px}

/* Page header split into title (left) and a record summary (right) instead of both stretching the
   full 1400px. 8/4 on desktop; one column below 900px so the summary sits under the title. */
.pagehead-split{display:grid;grid-template-columns:1fr;gap:var(--s4);align-items:start}
@media(min-width:901px){.pagehead-split{grid-template-columns:2fr 1fr;gap:var(--s5)}}

/* Labelled read-only rows — the label column carries the hierarchy, so every value is one size. */
.recordrows{display:grid;grid-template-columns:auto 1fr;gap:2px var(--s3);align-items:baseline}
.recordrows dt{font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-3);white-space:nowrap}
.recordrows dd{font-size:14px;line-height:1.45;word-break:break-word}
.recordrows dd.strong{font-weight:600}

.section-head{display:flex;align-items:center;justify-content:space-between;margin:var(--s6) 0 var(--s3)}
.section-head h2{font-size:18px;font-weight:600;letter-spacing:-.01em}
.section-head .link{font-size:13px;font-weight:600;color:var(--teal-deep)}
.link{color:var(--teal-deep);font-weight:600}
/* Button reset for in-page actions that look like text links (e.g. section-head "+ New …").
   Real <button>s, not <a href="#">: with <base href="/">, "#" resolves to the site root and
   Blazor's enhanced-nav interception navigates there before @onclick:preventDefault applies. */
.linkbtn{background:none;border:0;padding:0;font:inherit;cursor:pointer}
.linkbtn:hover{text-decoration:underline}
.stack{display:flex;flex-direction:column;gap:var(--s3)}
.grid{display:grid;gap:var(--s3)}
@media(min-width:680px){.grid-2{grid-template-columns:1fr 1fr}.grid-3{grid-template-columns:repeat(3,1fr)}.grid-4{grid-template-columns:repeat(4,1fr)}.grid-5{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1100px){.grid-5{grid-template-columns:repeat(5,1fr)}}
/* Two-column detail layout — one column on small screens, splits on large (PC) screens */
.detail-split{display:grid;gap:var(--s4);align-items:start;grid-template-columns:1fr;margin:var(--s4) 0 0}
@media(min-width:1000px){.detail-split{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}

/* In-page tab strip (Kit/Tabs) */
.tabstrip{display:flex;gap:var(--s2);border-bottom:1px solid var(--border);margin:var(--s4) 0;overflow-x:auto}
.tabstrip button{appearance:none;background:none;border:none;cursor:pointer;font:inherit;white-space:nowrap;
  padding:10px 12px;font-size:15px;font-weight:500;color:var(--text-3);
  border-bottom:3px solid transparent;border-radius:var(--r-sm) var(--r-sm) 0 0;
  transition:color .15s var(--ease),border-color .15s var(--ease),background-color .15s var(--ease)}
.tabstrip button:hover{color:var(--text);background:var(--surface-2)}
.tabstrip button.active{color:var(--text);font-weight:700;background:var(--surface-2);border-bottom-color:var(--teal)}
/* Opt-in sticky variant (Tabs Sticky param): pins the strip just under the fixed topnav while the
   page scrolls (64px bar on small screens; + the sub-nav on desktop — top values sit a couple px
   under the header so no gap ever shows). Opaque canvas bg, and the top margin becomes padding so
   passing content can't peek through above the strip. z stays under the topnav (40) / overlays. */
.tabstrip-sticky{position:sticky;top:60px;z-index:30;background:var(--bg);margin-top:0;padding-top:var(--s4)}
@media(min-width:900px){.tabstrip-sticky{top:112px}}

.tabstrip-count{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:999px;
  background:var(--surface-2);color:var(--text-2);font-size:12px;font-weight:600}
.tabstrip button.active .tabstrip-count{background:var(--teal);color:#fff}

/* Login / audit history rows */
.logrow{display:flex;gap:var(--s3);align-items:flex-start;padding:var(--s3) 0;border-bottom:1px solid var(--border)}
.logrow:last-child{border-bottom:none}
.logrow .logwhen{min-width:172px;font-size:13px;color:var(--text-2);white-space:nowrap}
.logrow .logbody{min-width:0;flex:1}
.logrow .logwhat{font-weight:600;font-size:14px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.logrow .logmeta{font-size:13px;color:var(--text-2);margin-top:3px;overflow-wrap:anywhere}
.logrow .logfield{font-size:12px;font-weight:600;color:var(--text-2);background:var(--surface-2);padding:1px 8px;border-radius:999px}
.logrow .auditval{font-weight:500}
.logrow .auditval.old{color:var(--text-2);text-decoration:line-through}
.logrow .auditval.new{color:var(--text)}
.logrow .auditarrow{margin:0 6px;color:var(--text-3)}
.logrow .auditby{margin-left:8px;color:var(--text-3)}
@media(max-width:560px){.logrow{flex-direction:column;gap:3px}.logrow .logwhen{min-width:0}}

.avatar{border-radius:50%;background:var(--surface-3);display:grid;place-items:center;font-weight:700;
  color:#fff;flex-shrink:0;font-size:13px;overflow:hidden}
.avatar.s{width:30px;height:30px;font-size:12px}
.avatar.m{width:42px;height:42px}
.avatar.l{width:64px;height:64px;font-size:22px}
.presence{position:relative}
.presence::after{content:"";position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;border-radius:50%;
  background:var(--teal);border:2.5px solid #fff}

/* ============================================================
   HERO / "WHAT NOW" CARD
   ============================================================ */
.hero{background:linear-gradient(140deg,var(--navy),var(--navy-deep));color:var(--text-on-navy);
  border-radius:var(--r-xl);padding:var(--s5);position:relative;overflow:hidden;border:none}
.hero::before{content:"";position:absolute;right:-60px;top:-60px;width:220px;height:220px;border-radius:50%;
  background:radial-gradient(circle,rgba(22,184,166,.4),transparent 70%)}
.hero .eyebrow{color:rgba(234,240,251,.7)}
.hero h2{font-size:22px;font-weight:700;letter-spacing:-.02em;margin:6px 0 6px;position:relative}
.hero p{color:rgba(234,240,251,.82);font-size:14px;margin-bottom:var(--s4);position:relative;max-width:46ch}
.hero .btn-primary{position:relative}

/* ============================================================
   JOURNEY PATH (visual, NOT a progress bar)
   ============================================================ */
.path{position:relative;padding:var(--s3) 0}
.path-track{display:flex;gap:0;align-items:flex-start;overflow-x:auto;padding:var(--s3) var(--s1) var(--s4);
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch}
.path-track::-webkit-scrollbar{height:0}
.node{flex:0 0 auto;width:128px;display:flex;flex-direction:column;align-items:center;text-align:center;
  scroll-snap-align:center;position:relative}
.node .seg{position:absolute;top:30px;left:50%;width:100%;height:4px;border-radius:2px;background:var(--surface-3);z-index:0}
.node:last-child .seg{display:none}
.node .seg.done{background:var(--teal)}
.node .bub{width:60px;height:60px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:18px;
  position:relative;z-index:1;border:3px solid #fff;transition:transform .2s var(--ease);background:var(--surface-3);color:var(--text-3)}
.node.done .bub{background:var(--teal);color:#fff;box-shadow:0 6px 16px rgba(22,184,166,.4)}
.node.current .bub{background:#fff;color:var(--teal-deep);border-color:var(--teal);box-shadow:0 0 0 4px var(--teal-wash);
  animation:pulse 2.4s var(--ease) infinite}
.node.locked .bub{background:var(--surface-2);color:var(--text-3)}
.node .wk{font-size:11px;font-weight:600;color:var(--text-3);margin-top:10px;letter-spacing:.04em;text-transform:uppercase}
.node .ti{font-size:12.5px;font-weight:600;margin-top:2px;color:var(--text);line-height:1.3;padding:0 4px}
.node.locked .ti{color:var(--text-3)}
.node button.bub{cursor:pointer}
.node button.bub:hover{transform:scale(1.06)}
@keyframes pulse{0%,100%{box-shadow:0 0 0 4px var(--teal-wash)}50%{box-shadow:0 0 0 9px var(--teal-wash)}}

/* ============================================================
   TASK ITEMS (actionable checklist)
   ============================================================ */
.task{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) var(--s4);border-radius:var(--r-md);
  background:var(--surface);border:1px solid var(--border);transition:transform .15s var(--ease),box-shadow .15s var(--ease),border-color .15s;
  cursor:pointer;text-align:left;width:100%}
.task:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm);border-color:var(--border-strong)}
.task .check{width:26px;height:26px;border-radius:50%;border:2px solid var(--border-strong);flex-shrink:0;
  display:grid;place-items:center;transition:all .2s var(--ease);position:relative}
.task .check svg{width:14px;height:14px;stroke-dasharray:20;stroke-dashoffset:20;transition:stroke-dashoffset .3s var(--ease) .05s}
.task.done .check{background:var(--teal);border-color:var(--teal)}
.task.done .check svg{stroke-dashoffset:0}
.task .body{flex:1;min-width:0}
.task .t{font-weight:600;font-size:14.5px;transition:color .2s}
.task.done .t{color:var(--text-3);text-decoration:line-through}
.task .meta{font-size:12.5px;color:var(--text-3);margin-top:2px;display:flex;gap:8px;align-items:center}
.task .go{color:var(--text-3);transition:transform .15s var(--ease)}
.task:hover .go{transform:translateX(3px);color:var(--teal-deep)}

/* ============================================================
   LEARN — week cards w/ states
   ============================================================ */
.week{display:flex;align-items:center;gap:var(--s4);padding:var(--s4) var(--s5);cursor:pointer}
.week .num{width:48px;height:48px;border-radius:var(--r-md);display:grid;place-items:center;font-weight:700;font-size:18px;flex-shrink:0}
.week.open .num{background:var(--teal-wash);color:var(--teal-deep)}
.week.done .num{background:var(--teal);color:#fff}
.week.closed .num,.week.locked .num{background:var(--surface-2);color:var(--text-3)}
.week .info{flex:1;min-width:0}
.week .info .wt{font-weight:600;font-size:15.5px}
.week .info .wm{font-size:13px;color:var(--text-2);margin-top:2px}
.week.locked{cursor:not-allowed;opacity:.72}
.bar{height:7px;border-radius:4px;background:var(--surface-3);overflow:hidden;margin-top:8px;max-width:240px}
.bar i{display:block;height:100%;background:var(--teal);border-radius:4px;transition:width .5s var(--ease)}

/* ============================================================
   COMMUNITY — threads
   ============================================================ */
.prompt-card{background:linear-gradient(135deg,var(--violet),#cc1543);color:#fff;border:none}
.prompt-card .eyebrow{color:rgba(255,255,255,.75)}
.prompt-card h3{font-size:18px;font-weight:600;margin:6px 0 6px;letter-spacing:-.01em}
.prompt-card p{color:rgba(255,255,255,.9);font-size:14px;margin-bottom:var(--s4)}
.thread{padding:var(--s4) var(--s5);cursor:pointer}
.thread .top{display:flex;align-items:center;gap:var(--s3);margin-bottom:8px}
.thread .who{font-weight:600;font-size:14px}
.thread .when{font-size:12px;color:var(--text-3)}
.thread .tt{font-weight:600;font-size:15.5px;margin-bottom:4px}
.thread .tx{font-size:14px;color:var(--text-2);overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.thread .foot{display:flex;align-items:center;gap:var(--s4);margin-top:var(--s3);font-size:13px;color:var(--text-3);font-weight:500}
.thread .foot .react:hover{color:var(--teal-deep)}
.thread .faces{display:flex}
.thread .faces .avatar{margin-left:-8px;border:2px solid #fff}
.thread .faces .avatar:first-child{margin-left:0}
.reply{display:flex;gap:var(--s3);padding:var(--s3) 0;border-top:1px solid var(--border)}
.reply .rb{flex:1}
.reply .rh{display:flex;align-items:center;gap:8px;margin-bottom:3px}
.reply .rn{font-weight:600;font-size:13.5px}
.reply .rw{font-size:11.5px;color:var(--text-3)}
.reply .rt{font-size:14px;color:var(--text);line-height:1.55}
.overdue-nudge{background:var(--amber-wash);border:1px solid rgba(39,39,124,.2);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  display:flex;align-items:center;gap:var(--s3);font-size:13.5px;color:#1a1a5c}
.overdue-nudge .chip{flex-shrink:0}

/* ============================================================
   SCHEDULE — calendar (scoped palette on .cal-shell)
   ============================================================ */
/* The calendar keeps its own token layer — the rules below are written against --cal-* so the palette
   can be re-pointed in one place — but each one now resolves to a design token rather than a literal,
   so the calendar follows the theme staff have chosen instead of staying on the original brand colours.
   Event kinds keep their distinct meanings: plenary = attention, cohort = primary, other = accent. */
.cal-shell{
  --cal-bg:var(--surface); --cal-surface:var(--surface-2); --cal-border:var(--border);
  --cal-today-bg:var(--amber); --cal-today-text:var(--text-on-navy);
  --cal-selected-bg:var(--teal); --cal-selected-text:var(--text-on-teal);
  --cal-hover-day:var(--teal-wash); --cal-text-primary:var(--text); --cal-text-secondary:var(--text-2);
  --cal-event-plenary:var(--amber); --cal-event-teal:var(--teal); --cal-event-amber:var(--violet);
  background:var(--cal-bg); border:1px solid var(--cal-border); border-radius:var(--r-md);
  box-shadow:var(--shadow-md); overflow:hidden;
}
.cal-legend{font-size:11px;font-weight:600;color:var(--text-3);display:flex;align-items:center;gap:5px}
.cal-legend .dot{width:8px;height:8px;border-radius:50%;display:inline-block}

/* --- FullCalendar: the schedule's full-page month view (2026-09-04) ---------------------------
   Replaced MonthCalendar's summary grid, whose .cal/.day/.ev-pill rules went with it. This one is a
   view rather than an index: every chip is a link to that meeting's page. Rows are a fixed height and
   overflow goes behind "+N more", so the month stays one rectangle whatever a single day holds. */
.fcal{display:flex;flex-direction:column}
.fcal-head{display:flex;align-items:center;gap:var(--s4);padding:var(--s4) var(--s5);flex-wrap:wrap}
.fcal-today{
  width:64px;flex:none;display:flex;flex-direction:column;align-items:stretch;gap:2px;
  border:1px solid var(--cal-border);border-radius:var(--r-sm);background:var(--cal-surface);padding:3px
}
.fcal-today-m{font-size:9.5px;font-weight:700;letter-spacing:.08em;color:var(--cal-text-secondary);text-align:center}
.fcal-today-d{
  font-size:18px;font-weight:800;line-height:1.3;text-align:center;color:var(--cal-text-primary);
  background:var(--cal-bg);border:1px solid var(--cal-border);border-radius:var(--r-sm)
}
.fcal-title{min-width:0;flex:1 1 220px}
.fcal-title h2{font-weight:700;font-size:19px;letter-spacing:-.01em}
.fcal-range{font-size:12.5px;color:var(--cal-text-secondary);margin-top:2px}
.fcal-head-end{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;margin-left:auto}
.fcal-key{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap}
/* One joined group of three, the way a segmented control reads — prev / reset / next. */
.fcal-nav{display:inline-flex;flex:none}
.fcal-nav-b{
  height:34px;min-width:34px;padding:0 10px;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--border);background:var(--surface);color:var(--text-2);
  font-size:13px;font-weight:600;margin-left:-1px;
  transition:background .15s var(--ease),border-color .15s var(--ease),color .15s var(--ease)
}
.fcal-nav-b:first-child{margin-left:0;border-radius:var(--r-sm) 0 0 var(--r-sm)}
.fcal-nav-b:last-child{border-radius:0 var(--r-sm) var(--r-sm) 0}
.fcal-nav-b:hover:not(:disabled){background:var(--surface-2);border-color:var(--border-strong);color:var(--text)}
.fcal-nav-b:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash);position:relative;z-index:1}
.fcal-nav-b:disabled{color:var(--text-3);cursor:default}
.fcal-nav-today{min-width:74px}

.fcal-dow{
  display:grid;grid-template-columns:repeat(7,1fr);border-top:1px solid var(--cal-border);
  border-bottom:1px solid var(--cal-border);background:var(--cal-surface)
}
.fcal-dow span{
  font-size:11px;font-weight:700;color:var(--cal-text-secondary);text-align:center;padding:9px 0;
  border-right:1px solid var(--cal-border)
}
.fcal-dow span:last-child{border-right:0}

.fcal-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.fcal-day{
  min-height:122px;display:flex;flex-direction:column;background:var(--cal-bg);
  border-right:1px solid var(--cal-border);border-bottom:1px solid var(--cal-border);
  padding:6px;gap:4px;overflow:hidden
}
.fcal-grid > .fcal-day:nth-child(7n){border-right:0}
/* Adjacent months stay visible but recede — the week is still a week, it just isn't this month. */
.fcal-day.out{background:var(--cal-surface)}
.fcal-day.out .fcal-day-num{color:var(--cal-text-secondary)}
.fcal-day-head{display:flex;align-items:center;justify-content:flex-end}
.fcal-day-num{
  font-size:12px;font-weight:600;color:var(--cal-text-primary);width:24px;height:24px;
  display:grid;place-items:center;border-radius:50%;flex:none
}
.fcal-day.today .fcal-day-num{background:var(--cal-today-bg);color:var(--cal-today-text);font-weight:700}
.fcal-day-body{display:flex;flex-direction:column;gap:3px;min-width:0}

.fcal-ev{
  display:block;text-decoration:none;border-radius:var(--r-sm);padding:4px 6px;min-width:0;
  border:1px solid transparent;transition:border-color .15s var(--ease),transform .15s var(--ease)
}
a.fcal-ev:hover{border-color:currentColor;transform:translateY(-1px)}
a.fcal-ev:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}
.fcal-ev-n{display:block;font-size:11px;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fcal-ev-t{display:block;font-size:10px;font-weight:600;opacity:.75;line-height:1.3;margin-top:1px}
.fcal-ev.navy{background:var(--amber-wash);color:var(--cal-event-plenary)}
.fcal-ev.teal{background:var(--teal-wash);color:var(--cal-event-teal)}
.fcal-ev.violet,.fcal-ev.coral{background:var(--violet-wash);color:var(--violet)}
.fcal-more{
  background:none;border:0;padding:2px 6px;text-align:left;cursor:pointer;
  font-size:10.5px;font-weight:700;color:var(--text-3);border-radius:var(--r-sm)
}
.fcal-more:hover{color:var(--text-2);background:var(--surface-2)}
.fcal-more:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}

/* the "+N more" day panel */
.fcal-daylist{display:flex;flex-direction:column;gap:var(--s2)}
.fcal-dayrow{
  display:flex;align-items:center;gap:var(--s3);text-decoration:none;color:inherit;
  border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s3)
}
a.fcal-dayrow:hover{border-color:var(--teal);background:var(--teal-wash)}
/* Base tokens, not the --cal-* layer: the panel is a Modal, so it renders outside .cal-shell and the
   scoped variables defined there would not resolve. Same colours, one indirection fewer. */
.fcal-dayrow-dot{width:10px;height:10px;border-radius:50%;flex:none;background:var(--text-3)}
.fcal-dayrow-dot.navy{background:var(--amber)}
.fcal-dayrow-dot.teal{background:var(--teal)}
.fcal-dayrow-dot.violet,.fcal-dayrow-dot.coral{background:var(--violet)}
.fcal-dayrow-t{min-width:0;flex:1}
.fcal-dayrow-n{display:block;font-weight:700;font-size:14px;letter-spacing:-.01em}
.fcal-dayrow-w{display:block;font-size:12px;color:var(--text-3);margin-top:2px}
.fcal-dayrow-go{font-size:12.5px;font-weight:700;color:var(--teal);flex:none}

/* Below the tablet break the month grid stops being readable at seven columns of cards, so the cells
   shrink to their date and a strip of dots and the panel becomes the way into a day. */
@media(max-width:760px){
  .fcal-head{padding:var(--s4)}
  .fcal-today{display:none}
  .fcal-day{min-height:74px;padding:4px}
  .fcal-ev-t{display:none}
  .fcal-ev-n{font-size:10px}
  .fcal-dow span{font-size:9.5px;padding:7px 0}
}
/* transient highlight when a calendar day jumps to its activity card */
.card.flash{box-shadow:0 0 0 3px rgba(22,184,166,.35),var(--shadow-md);border-color:var(--teal)}

/* --- the meeting page: /schedule/{id} and /schedule/one-on-one/{id} (2026-09-04) --------------
   One layout for every role. The main column is what the meeting IS — description, speakers,
   resources, and for a facilitator the controls that run it. The sidebar is what you DO about it, and
   it sticks, because the answer buttons are the reason most readers opened the page. */
.mtg-head{margin-bottom:var(--s5)}
.mtg-head .act-chips{margin-bottom:var(--s2)}
.mtg-head h1.page{margin:0}
.mtg-when{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:6px;font-size:14px}
.mtg-cols{display:grid;grid-template-columns:1fr;gap:var(--s4);align-items:start}
@media(min-width:900px){.mtg-cols{grid-template-columns:minmax(0,1fr) 320px;gap:var(--s5)}}
.mtg-main,.mtg-side{display:flex;flex-direction:column;gap:var(--s4);min-width:0}
@media(min-width:900px){.mtg-side{position:sticky;top:var(--s4)}}
.mtg-facts{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s3)}
.mtg-actions{display:flex;flex-direction:column;gap:var(--s2)}
.mtg-actions .sched-act-note{margin:0}
.mtg-att-row{display:flex;align-items:center;gap:12px;border-top:1px solid var(--border-strong);padding-top:10px}
.sess{display:flex;gap:var(--s4);padding:var(--s4) var(--s5);cursor:pointer;align-items:center}
.sess .time{text-align:center;flex-shrink:0;min-width:58px}
.sess .time .hr{font-weight:700;font-size:16px}
.sess .time .ap{font-size:11px;color:var(--text-3);font-weight:600}
.sess .bar-l{width:4px;align-self:stretch;border-radius:2px;background:var(--teal)}
.sess .bar-l.navy{background:var(--navy-soft)}
.sess .si{flex:1}
.sess .sn{font-weight:600;font-size:15px}
.sess .sm{font-size:13px;color:var(--text-2);margin-top:2px}

/* ============================================================
   MESSAGES
   ============================================================ */
.msg-row{display:flex;gap:var(--s3);padding:var(--s4) var(--s5);cursor:pointer;align-items:center}
.msg-row .mi{flex:1;min-width:0}
.msg-row .mn{font-weight:600;font-size:14.5px;display:flex;justify-content:space-between}
.msg-row .mn .mt{font-size:11.5px;color:var(--text-3);font-weight:500}
.msg-row .mp{font-size:13.5px;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}
.msg-row.unread .mp{color:var(--text);font-weight:500}
.msg-row .unreaddot{width:9px;height:9px;border-radius:50%;background:var(--teal);flex-shrink:0}
.bubble{max-width:78%;padding:10px 14px;border-radius:16px;font-size:14px;line-height:1.5}
.bubble.them{background:var(--surface-2);border-bottom-left-radius:5px;align-self:flex-start}
.bubble.me{background:var(--navy);color:#fff;border-bottom-right-radius:5px;align-self:flex-end}
.rte-toolbar{display:flex;gap:2px;padding:4px 6px;background:var(--surface-2);border:1px solid var(--border);border-bottom:none;border-radius:8px 8px 0 0}
.rte-toolbar button{padding:3px 9px;border:none;background:transparent;cursor:pointer;border-radius:5px;font-size:13px;font-weight:600;color:var(--text);line-height:1.4}
.rte-toolbar button:hover{background:var(--border)}
.rte-body{border:1px solid var(--border);border-radius:0 0 8px 8px;padding:8px 10px;min-height:110px;outline:none;font-size:14px;line-height:1.5;color:var(--text);overflow-y:auto;white-space:pre-wrap;word-break:break-word}
.rte-body:focus{border-color:var(--teal)}
.rte-body img{max-width:100%;height:auto;border-radius:6px;margin:4px 0}
.field-group-head{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3);margin:18px 0 8px;padding-bottom:6px;border-bottom:1px solid var(--border)}
.star-row{display:flex;gap:3px;align-items:center}
.star-btn{font-size:24px;background:none;border:none;cursor:pointer;padding:1px 2px;color:#d1d5db;line-height:1;transition:color .1s}
.star-btn.lit{color:var(--star)}
.field-list-row{display:flex;gap:8px;align-items:center;padding:9px 11px;border:1px solid var(--border);border-radius:10px;margin-bottom:6px}
.field-list-row:hover{border-color:var(--teal)}
.msg-thread{display:flex;flex-direction:column;gap:10px}
.composer{display:flex;gap:8px;padding-top:var(--s3);border-top:1px solid var(--border);margin-top:var(--s4)}
.composer input{flex:1;border:1.5px solid var(--border-strong);border-radius:var(--r-pill);padding:11px 16px;font-size:14px;outline:none;transition:border-color .15s}
.composer input:focus{border-color:var(--teal)}

/* ============================================================
   PROFILE / FORMS
   ============================================================ */
.field{margin-bottom:var(--s4)}
.field label{display:block;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text-2);margin-bottom:6px}
.field input,.field textarea,.field select{width:100%;border:1.5px solid var(--border-strong);border-radius:var(--r-md);
  padding:11px 14px;font-size:14px;outline:none;transition:border-color .15s,box-shadow .15s;background:#fff;color:var(--text)}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.field textarea{resize:vertical;min-height:80px}
.pwfield{position:relative}
.pwfield input{padding-right:42px}
.pwtoggle{position:absolute;top:50%;right:4px;transform:translateY(-50%);display:inline-flex;
  align-items:center;justify-content:center;width:34px;height:34px;border:0;border-radius:var(--r-md);
  background:none;color:var(--text-3);cursor:pointer}
.pwtoggle:hover{color:var(--text)}
.pwtoggle:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.pwtoggle-off{display:none}
.pwtoggle.is-shown .pwtoggle-on{display:none}
.pwtoggle.is-shown .pwtoggle-off{display:inline-flex}
.auth-card .pwtoggle{right:8px;width:40px;height:40px}
/* Label + HelpTip row (catalog help as a (?) popover): the row carries the label's bottom margin
   so the tip centers against the text instead of the text+margin box. */
.field .lblrow{margin-bottom:6px}
.field .lblrow label{margin-bottom:0}

/* Catalog-driven admin form (Staff contact editor): compact two-column grid; long-text fields span
   both columns; a section's checkboxes collect in a flag grid under the inputs. */
.formgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s4);row-gap:2px}
.formgrid .field{margin-bottom:var(--s3)}
.formgrid-span{grid-column:1/-1}
.flaggrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px var(--s4);
  margin-top:var(--s3);padding-top:var(--s3);border-top:1px solid var(--border)}
.flagitem{display:flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
@media (max-width:760px){.formgrid{grid-template-columns:1fr}.flaggrid{grid-template-columns:1fr 1fr}}

/* Kit TextArea — auto-growing long-text field with a live character counter. The wrapper's
   ::after replicates the text (data-rep) into the same grid cell with identical box metrics
   (box-sizing set explicitly: the * reset doesn't reach pseudo-elements), so the cell — and the
   textarea stretched to fill it — is always exactly as tall as the content: no inner scrollbar.
   Metrics are self-contained and the two-class selector outranks the generic .field textarea
   rules, so the field renders identically under both the .field and .fld/.inp form vocabularies. */
.txa-wrap{display:grid;width:100%}
.fld .txa-wrap{margin-top:5px}  /* matches .inp spacing inside label.fld */
.txa-wrap::after{content:attr(data-rep) " ";visibility:hidden;pointer-events:none}
.txa-wrap::after,.txa-wrap textarea.txa{grid-area:1/1/2/2;box-sizing:border-box;width:100%;
  min-height:80px;border:1.5px solid var(--border-strong);border-radius:var(--r-md);
  padding:11px 14px;background:#fff;color:var(--text);font-family:inherit;font-size:14px;
  font-weight:400;line-height:1.5;white-space:pre-wrap;overflow-wrap:break-word;word-break:normal;
  resize:none;overflow:hidden;outline:none;transition:border-color .15s,box-shadow .15s}
.txa-wrap textarea.txa:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.txa-count{margin-top:4px;font-size:12px;font-weight:400;color:var(--text-3);text-align:left;
  font-variant-numeric:tabular-nums}
.txa-count.at{color:var(--rose);font-weight:600}

.toggle{display:flex;align-items:center;justify-content:space-between;padding:var(--s3) 0;border-top:1px solid var(--border)}
.toggle .tl{font-size:14px;font-weight:500}
.toggle .ts{font-size:12.5px;color:var(--text-3);margin-top:1px}
.switch{width:46px;height:27px;border-radius:var(--r-pill);background:var(--surface-3);position:relative;transition:background .2s var(--ease);flex-shrink:0}
.switch::after{content:"";position:absolute;top:3px;left:3px;width:21px;height:21px;border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.2);transition:transform .2s var(--ease)}
.switch.on{background:var(--teal)}
.switch.on::after{transform:translateX(19px)}

/* ============================================================
   STAT TILES (staff/faculty/alumni)
   ============================================================ */
.stat{padding:var(--s4) var(--s5)}
.stat .v{font-size:30px;font-weight:300;letter-spacing:-.02em;line-height:1}
.stat .l{font-size:12.5px;color:var(--text-2);margin-top:6px;font-weight:500}
.stat .tr{font-size:12px;font-weight:600;color:var(--teal-deep);margin-top:6px}
/* A count that is bad news when it isn't zero (faculty "Falling behind"). Tinted rather than loud —
   it sits in a row of neutral tiles and has to read as one of them, just the one worth looking at. */
.stat-alert{background:var(--rose-wash)}
.stat-alert .v{color:#d84a4a}
.pdots{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px}

/* ============================================================
   INTERNAL NOTES (Kit/ContactNotesPanel — staff + cohort faculty only)
   ============================================================ */
.notes{margin-top:var(--s4)}
.notes-head{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s3)}
.notes-hint{font-size:12px}
/* Lede and quoted note inside the edit / delete dialogs. */
.notes-dialog-lede{margin:0 0 var(--s3);font-size:13px}
.notes-quote{background:var(--surface-2);border-left:3px solid var(--border-strong);
  border-radius:0 var(--r-sm) var(--r-sm) 0;padding:10px 14px;color:var(--text-2);
  white-space:pre-wrap;overflow-wrap:anywhere;margin:0}

/* --- the thread ------------------------------------------------------------
   A fixed-height pane rather than a growing list: the composer has to stay reachable while a long
   history scrolls behind it, which is the whole reason this reads as a conversation and not a feed. */
.chat{display:flex;flex-direction:column;height:min(560px,70vh);overflow:hidden}
.chat-scroll{flex:1;overflow-y:auto;padding:var(--s5);display:flex;flex-direction:column;gap:2px}
.chat-status{margin:auto 0}
.chat-day{align-self:center;margin:var(--s3) 0;padding:4px 12px;border-radius:var(--r-pill);
  background:var(--surface-2);color:var(--text-2);font-size:11px;font-weight:600;letter-spacing:.04em}

.chat-msg{display:flex;gap:10px;max-width:min(74%,560px);align-items:flex-end}
/* Yours on the right, everyone else's on the left — the one convention every reader already knows. */
.chat-msg.mine{align-self:flex-end;flex-direction:row-reverse}
.chat-msg.run{margin-top:var(--s3)}
/* Holds the avatar's column for the rest of a run, so consecutive notes stay aligned under it. */
.chat-gap{width:30px;flex:none}

.chat-bubble{position:relative;background:var(--surface-2);border:1px solid var(--border);
  border-radius:var(--r-md);padding:9px 13px 7px;min-width:120px}
.chat-msg.mine .chat-bubble{background:var(--teal-wash);border-color:rgba(22,184,166,.35)}
.chat-author{font-size:12px;font-weight:600;color:var(--violet-deep);margin-bottom:2px}
.chat-msg.mine .chat-author{color:var(--teal-deep);text-align:right}
/* Notes are plain text and often pasted from somewhere: keep the author's line breaks, and never let a
   long unbroken string (a URL, an id) push the bubble wider than the column. */
.chat-body{margin:0;white-space:pre-wrap;overflow-wrap:anywhere}
.chat-meta{display:flex;align-items:center;gap:6px;justify-content:flex-end;margin-top:3px;
  font-size:11px;color:var(--text-3);white-space:nowrap}
.chat-edited{font-style:italic}

/* Edit / delete, on hover, outside the bubble so they never sit on the words. Rendered only on notes
   the reader wrote, so their absence is the rule being shown rather than a state to explain. */
.chat-acts{position:absolute;top:4px;left:-4px;transform:translateX(-100%);display:flex;gap:2px;
  opacity:0;transition:opacity .12s var(--ease)}
.chat-msg:hover .chat-acts,.chat-acts:focus-within{opacity:1}
.chat-acts button{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:var(--surface);border:1px solid var(--border);color:var(--text-2);cursor:pointer;
  box-shadow:var(--shadow-sm)}
.chat-acts button:hover{color:var(--text);border-color:var(--border-strong)}
.chat-acts button.del:hover{color:var(--rose);border-color:var(--rose)}
.chat-acts button:disabled{opacity:.5;cursor:not-allowed}

/* --- the composer --- */
.chat-composer{border-top:1px solid var(--border);background:var(--surface);
  padding:var(--s3) var(--s4);display:flex;align-items:flex-end;gap:var(--s3)}
.chat-field{flex:1;min-width:0}
/* The Kit TextArea, dressed as a chat input: pill, tinted until focus, one line tall to start.
   Both halves of the auto-grow pair are restyled together — the invisible ::after replicant is what
   actually sets the height, so a rule that reached only the textarea would leave the box the size of
   the replicant and the two would disagree. Capping both stops a pasted essay from swallowing the
   thread: the replicant stops growing at 140px and the textarea scrolls inside it from there.
   The two-class selectors below have to out-rank .txa-wrap textarea.txa, hence the full path. */
.chat-field .txa-wrap::after,
.chat-field .txa-wrap textarea.txa{min-height:44px;max-height:140px;padding:11px 15px;
  border-radius:var(--r-lg);border-width:1px;border-color:var(--border);background:var(--surface-2)}
.chat-field .txa-wrap::after{overflow:hidden}
.chat-field .txa-wrap textarea.txa{overflow-y:auto}
.chat-field .txa-wrap textarea.txa:focus{background:var(--surface)}
.chat-field .txa-count{margin-top:2px;font-size:11px;text-align:right}
.chat-send{width:44px;height:44px;border-radius:50%;border:0;flex:none;margin-bottom:18px;
  display:grid;place-items:center;background:var(--teal);color:var(--text-on-teal);cursor:pointer;
  box-shadow:0 4px 14px rgba(22,184,166,.32);transition:background .12s var(--ease)}
.chat-send:hover{background:var(--teal-deep)}
.chat-send:active{transform:scale(.96)}
.chat-send:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}

@media (max-width:640px){
  .chat{height:min(70vh,520px)}
  .chat-scroll{padding:var(--s4)}
  .chat-msg{max-width:88%}
}

/* One line of the faculty dashboard's "what's next" cards: title + when on the left, Join on the right. */
.fd-upcoming{display:flex;align-items:center;gap:var(--s3);border-top:1px solid var(--border);padding-top:10px}
.fd-upcoming:first-child{border-top:0;padding-top:0}
.fd-upcoming .fd-go{margin-left:auto;flex:none}
.fd-study{margin-top:var(--s4)}
.fd-study-body{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap}
.fd-study-text{flex:1;min-width:240px}
.fd-study-title{font-size:17px;font-weight:600;margin:4px 0 2px}
.fd-study-copy{font-size:13px;margin:0}
.fd-study-count{font-size:13px;color:var(--text-2);margin:8px 0 0}
/* A fellow's written study response on the faculty fellow page — quoted, since it is their words. */
.fd-response{margin:var(--s3) 0 0;padding:10px var(--s3);border-left:3px solid var(--teal);
  background:var(--surface-2);border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:14px;line-height:1.5;
  white-space:pre-wrap;color:var(--text-2)}
.pdots i{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:700;
  font-style:normal;background:var(--surface-3);color:var(--text-3);border:1px solid var(--border)}
.pdots i.on{background:var(--teal);color:#fff;border-color:var(--teal)}

/* data table — STAFF ONLY (members never see tables) */
/* horizontal scroll container: keeps wide tables inside the card instead of
   overflowing past its right edge; inherits the card's rounded corners. */
.tbl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:inherit}
.tbl{width:100%;border-collapse:collapse;font-size:14px}
.tbl th{text-align:left;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--text-3);
  padding:10px 14px;border-bottom:1px solid var(--border)}
.tbl td{padding:12px 14px;border-bottom:1px solid var(--border)}
.tbl tr{transition:background .12s}
.tbl tbody tr:hover{background:var(--surface-2)}
.tbl tr td:last-child{text-align:right}
/* Action cluster in a row's last cell (e.g. Fellows → Impersonate + Edit). The inline form
   keeps its submit button on the same line as the sibling link. */
.row-actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--s2);flex-wrap:wrap}
.row-actions-form{margin:0;display:inline-flex}
/* column resizing — opt-in via <ListView Resizable="true">. JS measures the auto layout, switches the
   table to fixed layout, then a drag handle on each header's right edge adjusts widths (persisted per
   list). Fixed layout means cells clip rather than spill, so overflow is hidden. */
.tbl-resizable thead th{position:relative}
.tbl-resizable th,.tbl-resizable td{overflow:hidden}
.col-resizer{position:absolute;top:0;right:0;width:9px;height:100%;cursor:col-resize;
  touch-action:none;user-select:none;z-index:3}
.col-resizer::after{content:"";position:absolute;top:25%;right:4px;width:2px;height:50%;
  border-radius:2px;background:transparent;transition:background .12s}
.col-resizer:hover::after{background:var(--border-strong)}
body.col-resizing,body.col-resizing *{cursor:col-resize!important;user-select:none!important}

/* opportunity cards (alumni) */
.opp{padding:var(--s5)}
.opp .ot{font-weight:600;font-size:16px;margin:8px 0 4px}
.opp .om{font-size:13px;color:var(--text-2)}
.opp .od{font-size:14px;color:var(--text-2);margin:var(--s3) 0}

/* ============================================================
   ROLE SWITCHER (floating)
   ============================================================ */
.roleswitch{position:fixed;right:18px;bottom:104px;z-index:60}
@media(min-width:900px){.roleswitch{bottom:24px;right:24px}}
.roleswitch .fab{display:flex;align-items:center;gap:8px;background:var(--navy);color:#fff;border-radius:var(--r-pill);
  padding:11px 16px;box-shadow:var(--shadow-lg);font-weight:600;font-size:13px;transition:transform .15s var(--ease)}
.roleswitch .fab:hover{transform:translateY(-2px)}
.roleswitch .fab .dotc{width:8px;height:8px;border-radius:50%;background:var(--teal)}
.role-menu{position:absolute;bottom:56px;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg);padding:8px;width:230px;opacity:0;transform:translateY(8px) scale(.97);pointer-events:none;
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
.role-menu.open{opacity:1;transform:none;pointer-events:auto}
.role-menu .rm-head{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);padding:8px 10px 6px}
.role-menu button{display:flex;align-items:center;gap:10px;width:100%;padding:10px;border-radius:var(--r-md);text-align:left;
  transition:background .12s}
.role-menu button:hover{background:var(--surface-2)}
.role-menu button.active{background:var(--teal-wash)}
.role-menu .ri{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;color:#fff;font-weight:700;font-size:13px;flex-shrink:0}
.role-menu .rname{font-weight:600;font-size:14px}
.role-menu .rdesc{font-size:11.5px;color:var(--text-3)}

/* ============================================================
   MODAL
   ============================================================ */
/* A closed scrim stays in the DOM, so opacity alone would leave its buttons in the tab order and its
   role="dialog" in the accessibility tree. visibility:hidden removes both; the delayed visibility
   transition lets the fade-out finish before it disappears. */
/* No backdrop-filter, permanently (2026-08-28). Its blur smeared into the modal's own content —
   the last line of text picked up the backdrop's blur — so the frosted look isn't worth it. The
   half-opacity navy dim does the separating on its own. Don't add it back. */
.scrim{position:fixed;inset:0;background:rgba(15,24,48,.5);z-index:80;
  opacity:0;pointer-events:none;visibility:hidden;
  transition:opacity .2s var(--ease),visibility 0s linear .2s;display:grid;place-items:end center}
.scrim.open{opacity:1;pointer-events:auto;visibility:visible;
  transition:opacity .2s var(--ease),visibility 0s}
/* Scroll lock on BODY only, never html. Hiding overflow on the root element discards the document's
   scroll position — the reset happens invisibly behind the fixed scrim the moment a modal opens, so
   closing one dumped the reader at the top of the page. body's hidden overflow still propagates to
   the viewport (nothing scrolls while the dialog is up) but the position survives the round trip. */
body:has(.scrim.open){overflow:hidden}
.modal{background:#fff;width:100%;max-width:560px;max-height:calc(100dvh - var(--s5));display:flex;flex-direction:column;overflow:hidden;border-radius:var(--r-xl) var(--r-xl) 0 0;
  transform:translateY(40px);transition:transform .26s var(--ease);box-shadow:var(--shadow-lg)}
.scrim.open .modal{transform:none}
/* The entrance is a plain rise — no scale(.97). Animating scale rasterizes the dialog's text at 97%
   and Chrome can keep that raster after the transition ends, leaving every glyph slightly blurred
   for the modal's whole life. translateY moves the layer without resampling it. */
@media(min-width:900px){.scrim{place-items:center}.modal{max-height:calc(100dvh - var(--s7));border-radius:var(--r-xl);transform:translateY(20px)}.modal.wide{max-width:720px}.modal.xl{max-width:900px}}
.modal-grip{width:40px;height:4px;border-radius:2px;background:var(--border-strong);margin:10px auto 0;flex-shrink:0}
@media(min-width:900px){.modal-grip{display:none}}
.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);padding:var(--s5) var(--s5) var(--s3);flex-shrink:0}
.modal-head-actions{display:flex;gap:8px;align-items:center;margin-left:auto}
.modal-head h3{font-size:19px;font-weight:600;letter-spacing:-.01em}
.modal-x{width:34px;height:34px;border-radius:50%;background:var(--surface-2);display:grid;place-items:center;flex-shrink:0;
  transition:background .12s}
.modal-x:hover{background:var(--surface-3)}
.modal-body{padding:0 var(--s5) var(--s5);overflow-y:auto;flex:1 1 auto;-webkit-overflow-scrolling:touch}
/* Modal Padded="false": edge-to-edge sections that pick their own scroller (see .pm-cols). */
.modal-body.modal-body-flush{padding:0;overflow:hidden;display:flex;flex-direction:column}
/* Modal SlimHead="true": a thin chrome strip carrying controls instead of a title. */
.modal-head.modal-head-slim{align-items:center;padding:var(--s2) var(--s3) var(--s2) var(--s5);
  border-bottom:1px solid var(--border);gap:var(--s1)}
.modal-head-slim .modal-head-actions{gap:var(--s1)}

/* ---- (?) explainer beside a label (Kit/HelpTip) ---- */
.check-row{display:flex;align-items:center;gap:6px}
.helptip{width:18px;height:18px;border-radius:50%;flex:0 0 auto;display:inline-grid;place-items:center;
  background:var(--surface-3);color:var(--text-2);font-size:11.5px;font-weight:700;line-height:1;
  transition:background .12s var(--ease),color .12s var(--ease)}
.helptip:hover{background:var(--navy);color:var(--text-on-navy)}
.helptip:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash);background:var(--navy);color:var(--text-on-navy)}
.helptip-body{display:flex;flex-direction:column;gap:var(--s3);font-size:14px;color:var(--text-2)}
.helptip-body strong{color:var(--text)}
/* Hover/focus popover — appears above the (?) icon; click still opens the Modal (touch path). */
.helptip-wrap{position:relative;display:inline-flex;flex:0 0 auto}
.helptip-pop{position:absolute;bottom:calc(100% + 9px);left:50%;transform:translateX(-50%) translateY(3px);
  width:max-content;max-width:300px;background:var(--navy);color:var(--text-on-navy);border-radius:var(--r-md);
  padding:10px 13px;font-size:12.5px;font-weight:400;line-height:1.55;text-align:left;white-space:normal;
  box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;pointer-events:none;z-index:71;
  transition:opacity .15s var(--ease),transform .15s var(--ease),visibility .15s var(--ease)}
.helptip-pop::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:6px solid transparent;border-top-color:var(--navy)}
.helptip-pop-title{display:block;font-weight:700;font-size:12px;letter-spacing:.02em;margin-bottom:4px;color:#fff}
.helptip-pop p{margin:0}
.helptip-pop p+p{margin-top:6px}
.helptip-pop strong{color:#fff;font-weight:600}
.helptip-wrap:hover .helptip-pop,
.helptip:focus-visible+.helptip-pop{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
/* Inside a modal the scrollport (overflow:hidden/auto) would clip the popover — suppress it there;
   clicking the (?) opens the explainer dialog instead, same as before. */
.modal .helptip-pop{display:none}

/* Inline defined term — a dotted-underlined phrase whose definition pops up on hover or keyboard
   focus (e.g. "Changemakers Network Leader" on a directory profile). Unlike .helptip-pop this one
   is fine inside a modal: it lives in a non-scrolling strip, pops upward into the dialog, and is
   anchored to the term's left edge so it can't slide past the modal's boundary and get clipped. */
.termtip{position:relative;display:inline-block;border-bottom:1px dotted var(--text-3);cursor:help;font-style:inherit}
.termtip:focus-visible{outline:none;border-bottom-color:var(--teal-deep);color:var(--teal-deep)}
.termtip-pop{position:absolute;bottom:calc(100% + 9px);left:-6px;transform:translateY(3px);
  width:max-content;max-width:280px;background:var(--navy);color:var(--text-on-navy);border-radius:var(--r-md);
  padding:10px 13px;font-size:12.5px;font-weight:400;font-style:normal;line-height:1.55;text-align:left;
  white-space:normal;box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;pointer-events:none;z-index:71;
  transition:opacity .15s var(--ease),transform .15s var(--ease),visibility .15s var(--ease)}
.termtip-pop::after{content:"";position:absolute;top:100%;left:34px;transform:translateX(-50%);
  border:6px solid transparent;border-top-color:var(--navy)}
.termtip:hover .termtip-pop,.termtip:focus-visible .termtip-pop{opacity:1;visibility:visible;transform:translateY(0)}

/* ============================================================
   ACTIVITIES — toolbar + the two card arrangements
   "grid" = type band (tinted header strip);  "list" = date rail
   (calendar tear-off down the left edge). One component, two shapes.
   Each card is a native <button>, so keyboard + screen-reader
   behaviour comes for free.
   ============================================================ */
.act-toolbar{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s4)}
.act-toolbar .act-count{margin-bottom:0;margin-right:auto}

/* ---- sort dropdown (Kit/SortSelect) ---- */
.sortsel{position:relative;display:inline-flex;align-items:center;flex:none}
.sortsel select{appearance:none;-webkit-appearance:none;font:inherit;font-size:13px;font-weight:600;
  color:var(--text-2);background:var(--surface-2);border:1.5px solid transparent;border-radius:var(--r-pill);
  padding:8px 32px 8px 34px;cursor:pointer;transition:border-color .14s var(--ease),background .14s var(--ease)}
.sortsel select:hover{border-color:var(--border-strong)}
.sortsel select:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.sortsel-ic{position:absolute;left:12px;color:var(--text-3);pointer-events:none;display:inline-flex}
.sortsel-caret{position:absolute;right:11px;color:var(--text-3);pointer-events:none;display:inline-flex}

/* ---- card wall ---- */
.ac-stack{display:grid;gap:var(--s4)}
.ac-stack-grid{grid-template-columns:1fr}
@media(min-width:600px){.ac-stack-grid{grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}}
.ac-stack-list{grid-template-columns:1fr;gap:var(--s3)}
@media(min-width:1100px){.ac-stack-list{grid-template-columns:repeat(auto-fill,minmax(430px,1fr))}}

/* ---- shared card shell ---- */
.ac{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);display:flex;overflow:hidden;width:100%;text-align:left;cursor:pointer;
  transition:box-shadow .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease)}
.ac:hover{box-shadow:var(--shadow-md);border-color:var(--border-strong);transform:translateY(-3px)}
.ac:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash),var(--shadow-md)}
.ac-grid{flex-direction:column}
.ac-list{flex-direction:row;align-items:stretch}

/* one hue per activity family — set once here, consumed by both arrangements */
.ac-t1{--accent:var(--teal);--accent-deep:var(--teal-deep);--accent-wash:var(--teal-wash)}
.ac-t2{--accent:var(--violet);--accent-deep:var(--violet-deep);--accent-wash:var(--violet-wash)}
.ac-t3{--accent:var(--amber);--accent-deep:var(--amber-deep);--accent-wash:var(--amber-wash)}
.ac-t4{--accent:var(--navy-soft);--accent-deep:var(--navy);--accent-wash:var(--surface-3)}
.ac-t5{--accent:var(--teal-deep);--accent-deep:var(--teal-press);--accent-wash:var(--teal-wash)}

.ac-body{flex:1;min-width:0;display:flex;flex-direction:column;padding:var(--s4)}
.ac-name{font-weight:600;font-size:15px;line-height:1.32;letter-spacing:-.01em;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ac-when{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:var(--text-2);margin-top:8px}
.ac-sub{font-size:12.5px;color:var(--text-3);margin-top:5px;
  display:-webkit-box;-webkit-line-clamp:1;line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
.ac-foot{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
  margin-top:auto;padding-top:10px}
.ac-grid .ac-foot{margin-top:var(--s3);padding-top:10px;border-top:1px solid var(--border)}
.ac-foot:empty{display:none}
.ac-tag{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;color:var(--text-3)}
.ac-done{margin-left:auto;display:inline-flex;align-items:center;gap:5px;
  font-size:11.5px;font-weight:600;color:var(--teal-deep)}
.ac-rate{margin-left:auto;display:inline-flex}

/* ---- "grid" = type band ---- */
.ac-band{display:flex;align-items:center;gap:8px;padding:9px var(--s4);
  background:var(--accent-wash);border-bottom:1px solid var(--border)}
.ac-band-ic{width:22px;height:22px;border-radius:7px;background:var(--accent);color:var(--text-on-teal);
  display:grid;place-items:center;flex:none}
.ac-band-type{font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent-deep)}
.ac-band-flag{margin-left:auto;display:inline-flex;align-items:center;gap:4px;
  font-size:11px;font-weight:600;color:var(--text-3)}
.ac-grid.done .ac-band{background:var(--teal-wash)}
.ac-grid.done .ac-band-ic{background:var(--teal)}
.ac-grid.done .ac-band-type,.ac-grid.done .ac-band-flag{color:var(--teal-deep)}

/* ---- "list" = date rail ---- */
.ac-rail{flex:0 0 76px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:var(--s4) 0;background:var(--surface-2);border-right:1px solid var(--border)}
.ac-list.done .ac-rail{background:var(--teal-wash)}
.ac-rail-mo{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-deep)}
.ac-rail-dy{font-size:27px;font-weight:700;letter-spacing:-.03em;line-height:1.05;margin-top:1px}
.ac-rail-wd{font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);margin-top:2px}
.ac-rail-glyph{color:var(--accent-deep);display:grid;place-items:center;height:44px}
.ac-rail-tm{margin-top:8px;padding-top:6px;width:46px;text-align:center;
  font-size:10.5px;font-weight:600;color:var(--text-3);border-top:1px solid var(--border-strong)}
.ac-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ac-type{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--accent-deep)}
.ac-pin{color:var(--text-3);display:inline-flex}
.ac-list .ac-name{margin-top:5px}

/* ---------- detail modal ---------- */
.act-hero{margin:0 calc(var(--s5) * -1) var(--s4);height:190px;overflow:hidden;background:var(--surface-2)}
.act-hero img{display:block;width:100%;height:100%;object-fit:cover}
.act-chips{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}

.act-done{display:flex;align-items:center;gap:10px;margin-top:var(--s4);padding:var(--s3) var(--s4);
  background:var(--teal-wash);border:1px solid rgba(22,184,166,.3);border-radius:var(--r-md);
  color:var(--teal-deep);font-size:13.5px;font-weight:600}
.act-done .ic{width:26px;height:26px;border-radius:50%;background:var(--teal);color:#fff;
  display:grid;place-items:center;flex:0 0 auto}

.act-meta{display:grid;grid-template-columns:1fr;gap:var(--s3);margin-top:var(--s4);
  padding:var(--s4);background:var(--surface-2);border-radius:var(--r-md)}
@media(min-width:680px){.act-meta{grid-template-columns:1fr 1fr;gap:var(--s4)}}
.act-meta-item{display:flex;align-items:flex-start;gap:10px;min-width:0}
.act-meta-ic{width:32px;height:32px;border-radius:10px;background:var(--surface);color:var(--teal-deep);
  display:grid;place-items:center;flex:0 0 auto;box-shadow:var(--shadow-sm)}
.act-meta-t{display:flex;flex-direction:column;min-width:0}
.act-meta-k{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3)}
.act-meta-v{font-size:14px;font-weight:500;color:var(--text);margin-top:1px;overflow-wrap:anywhere}

.act-sec{margin-top:var(--s5)}
.act-sec-h{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-3);margin-bottom:var(--s2)}
/* Full-strength text, not --text-2: this is the dialog's body copy, and a paragraph of the muted
   caption gray at this size read as faded next to the meta values above it. */
.act-prose{font-size:14.5px;line-height:1.65;color:var(--text);white-space:pre-wrap}

.act-speaker{display:flex;align-items:flex-start;gap:var(--s3);padding:var(--s3);
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface)}
.act-speaker + .act-speaker{margin-top:var(--s2)}
.act-speaker-t{min-width:0}
.act-speaker-n{font-weight:600;font-size:14.5px}
.act-speaker-o{font-size:12.5px;color:var(--text-3);margin-top:1px}
.act-speaker-b{font-size:13.5px;line-height:1.55;color:var(--text-2);margin-top:6px}
.act-speaker-l{display:flex;gap:var(--s3);flex-wrap:wrap;margin-top:8px;font-size:12.5px}

.act-res{display:flex;align-items:center;gap:var(--s3);padding:11px var(--s3);
  border:1px solid var(--border);border-radius:var(--r-md);
  transition:border-color .15s var(--ease),background .15s var(--ease)}
.act-res + .act-res{margin-top:var(--s2)}
.act-res:hover{border-color:var(--teal);background:var(--teal-wash)}
/* Viewable-but-gated resources: names show, nothing opens until the event is live or past. */
.act-res.locked{opacity:.6;cursor:default;pointer-events:none}
.act-res.locked:hover{border-color:var(--border);background:transparent}
.act-res.locked .act-res-go{color:var(--text-3)}
.act-res-note{font-size:12.5px;color:var(--text-3);margin:0 0 var(--s2)}
.act-res-ic{width:34px;height:34px;border-radius:10px;background:var(--surface-2);color:var(--navy);
  display:grid;place-items:center;flex:0 0 auto}
.act-res-t{display:flex;flex-direction:column;min-width:0}
.act-res-n{font-weight:600;font-size:14px}
.act-res-s{font-size:12px;color:var(--text-3);overflow-wrap:anywhere}
.act-res-go{margin-left:auto;font-size:13px;font-weight:600;color:var(--teal-deep);white-space:nowrap}

/* Optional rating + comment captured with a completion. Never gates the Mark complete button. */
.act-fb{background:var(--surface-2);border-radius:var(--r-md);padding:var(--s4)}
.act-fb .act-sec-h{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s3)}
.act-fb-opt{font-size:10.5px;font-weight:600;letter-spacing:.04em;color:var(--text-3);
  background:var(--surface);border-radius:var(--r-pill);padding:2px 8px;text-transform:none}
.act-fb-text{margin-top:var(--s3);width:100%;resize:vertical;min-height:76px}
.act-fb-foot{display:flex;align-items:baseline;gap:var(--s3);margin-top:6px}
.act-fb-note{font-size:11.5px;color:var(--text-3);line-height:1.45}
.act-fb-count{margin-left:auto;font-size:11.5px;color:var(--text-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.act-fb-count.at-limit{color:var(--rose);font-weight:600}

/* The member's own feedback, read back once the activity is complete. */
.act-myfb{margin-top:var(--s3);padding:var(--s3) var(--s4);border:1px solid var(--border);border-radius:var(--r-md)}
.act-myfb .act-sec-h{margin-bottom:6px}
.act-myfb-c{margin-top:8px;font-size:13.5px;line-height:1.55;color:var(--text-2);white-space:pre-wrap}

/* Sticky action bar — full-bleed inside the scrolling .modal-body. Solid (not translucent) so
   content passing underneath never ghosts through the divider. No ::before scroll-fade gradient
   above it any more (2026-08-28): it sat on top of whatever ended just above the bar, washing out
   the description's last line even when nothing scrolled. Don't add it back. */
.act-bar{position:sticky;bottom:0;z-index:1;display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;
  margin:var(--s6) calc(var(--s5) * -1) calc(var(--s5) * -1);padding:var(--s4) var(--s5);
  background:var(--surface);border-top:1px solid var(--border)}
.act-bar-end{margin-left:auto;display:inline-flex;align-items:center;gap:var(--s2)}

/* ============================================================
   CELEBRATION / TOAST
   ============================================================ */
.toast-wrap{position:fixed;left:0;right:0;bottom:108px;z-index:90;display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none}
@media(min-width:900px){.toast-wrap{bottom:24px;right:24px;left:auto;align-items:flex-end}}
.toast{background:var(--navy);color:#fff;padding:12px 18px;border-radius:var(--r-pill);font-size:14px;font-weight:600;
  box-shadow:var(--shadow-lg);display:flex;align-items:center;gap:10px;transform:translateY(20px);opacity:0;
  transition:transform .3s var(--ease),opacity .3s var(--ease)}
.toast.show{transform:none;opacity:1}
.toast .tdot{width:22px;height:22px;border-radius:50%;background:var(--teal);display:grid;place-items:center;flex-shrink:0}
#confetti{position:fixed;inset:0;pointer-events:none;z-index:100}

@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
}
.fade-in{animation:fadeIn .35s var(--ease)}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ============================================================
   MEDIA SYSTEM
   ============================================================ */
.cover{position:relative;width:100%;overflow:hidden;background:var(--surface-2);border-radius:inherit}
.cover.r-16x9{aspect-ratio:16/9}
.cover.r-1x1{aspect-ratio:1/1}
.cover img{width:100%;height:100%;object-fit:cover;display:block}
.cover .ph{position:absolute;inset:0;display:grid;place-items:center;color:rgba(255,255,255,.95)}
.cover .ph .glyph{opacity:.92}
.cover .ph .lbl{position:absolute;left:14px;bottom:12px;font-size:12.5px;font-weight:700;color:#fff;text-shadow:0 1px 8px rgba(0,0,0,.45);letter-spacing:-.01em}
.cover.loading .ph{opacity:0}
.shimmer{background:linear-gradient(100deg,var(--surface-2) 28%,var(--surface-3) 50%,var(--surface-2) 72%);background-size:200% 100%;animation:sh 1.3s var(--ease) infinite}
@keyframes sh{0%{background-position:200% 0}100%{background-position:-200% 0}}
.avatar img{width:100%;height:100%;object-fit:cover;border-radius:inherit}
.avatar.up{cursor:pointer;position:relative}
.avatar.up::after{content:"";position:absolute;inset:0;border-radius:50%;box-shadow:inset 0 0 0 2px rgba(255,255,255,.4);opacity:0;transition:opacity .15s}
.avatar.up:hover::after{opacity:1}

/* Avatar upload (Kit/AvatarUpload) */
/* Logo upload (Kit/LogoUpload.razor) — like the avatar uploader but no square crop; keeps the logo's shape */
.logoupload{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap}
.logoupload-preview{display:flex;align-items:center;justify-content:center;min-width:150px;height:88px;
  padding:12px 16px;border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface-2)}
.logoupload-preview img{max-height:64px;max-width:220px;width:auto;object-fit:contain;display:block}
.logoupload-preview.is-dark{border-color:transparent;
  background:linear-gradient(160deg,var(--navy) 0%,var(--navy-deep) 100%)}
.logoupload-empty{font-size:12px;color:var(--text-2)}
.logoupload-preview.is-dark .logoupload-empty{color:var(--text-on-navy)}
.logoupload-body{display:flex;flex-direction:column;gap:6px;min-width:0}
.logoupload-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.logoupload-hint{font-size:12px;color:var(--text-2);margin:0}
.logoupload-pick{cursor:pointer;margin:0}
.logoupload-pick.is-busy{opacity:.6;pointer-events:none}
.logoupload-fileinput{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;clip:rect(0,0,0,0);pointer-events:none}

/* Certificate designer (Kit/CertificateDesigner.razor + CertificateDesigner.js).
   The stage is the positioning context: the canvas paints the artwork, the layer holds the draggable
   field boxes on top of it. Both are sized in px by the JS from the PDF.js viewport. */
.certdesign{display:flex;flex-direction:column;gap:8px}
/* isolation:isolate so a selected box's z-index can't paint over the loading veil. */
.certdesign-stage{position:relative;align-self:center;max-width:100%;background:var(--surface-2);border-radius:var(--r-md);isolation:isolate}
.certdesign-canvas{display:block;max-width:100%}
.certdesign-layer{position:absolute;inset:0}
.certdesign-veil{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;background:var(--surface-2);color:var(--text-2);font-size:14px;text-align:center;padding:16px}
.certdesign-hint{font-size:12px;color:var(--text-2);margin:0;text-align:center}

/* The field table row matching the box selected on the canvas. */
tr.is-picked>td{background:color-mix(in srgb,var(--teal) 8%,transparent)}
tr.is-picked{cursor:pointer}

.certdesign-box{position:absolute;box-sizing:border-box;cursor:grab;outline:1px dashed color-mix(in srgb,var(--navy) 45%,transparent);min-height:8px;touch-action:none}
.certdesign-box:hover{outline-color:var(--navy)}
.certdesign-box.is-selected{outline:2px solid var(--teal);z-index:2}
.certdesign-box.is-off{opacity:.4}
.certdesign-box:active{cursor:grabbing}
.certdesign-text{display:block;white-space:nowrap;line-height:1.15;pointer-events:none}
/* The field's name, shown above its box on hover/selection so overlapping boxes stay tellable apart.
   Sits inside the box for a field near the page top, where there's no room above it. */
.certdesign-tag{position:absolute;left:0;bottom:100%;margin-bottom:2px;padding:1px 5px;border-radius:4px;background:var(--navy);color:var(--text-on-navy);font-size:10px;line-height:1.5;white-space:nowrap;opacity:0;transition:opacity .12s;pointer-events:none}
.certdesign-box:hover .certdesign-tag,.certdesign-box.is-selected .certdesign-tag{opacity:1}
/* Right-edge grip: drag to set the field's width. */
.certdesign-grip{position:absolute;top:0;right:-3px;width:8px;height:100%;cursor:ew-resize;background:transparent}
.certdesign-box:hover .certdesign-grip,.certdesign-box.is-selected .certdesign-grip{background:linear-gradient(to right,transparent,color-mix(in srgb,var(--teal) 50%,transparent))}

/* Generic file picker (Kit/FileUpload.razor) — a styled label over a visually hidden input. */
.fileupload{display:inline-flex;align-items:center}
.fileupload-pick{cursor:pointer;margin:0}
.fileupload-pick.is-busy{opacity:.6;pointer-events:none}
.fileupload-input{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;clip:rect(0,0,0,0);pointer-events:none}

.avatarupload{display:flex;align-items:center;gap:var(--s4)}
.avatarupload-body{display:flex;flex-direction:column;gap:6px;min-width:0}
.avatarupload-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.avatarupload-hint{font-size:12px;color:var(--text-2);margin:0}
.avatarupload-pick{cursor:pointer;margin:0}
.avatarupload-pick.is-busy{opacity:.6;pointer-events:none}
.avatarupload-fileinput{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;clip:rect(0,0,0,0);pointer-events:none}

/* Avatar crop modal (driven by AvatarUpload.js) */
.avatarcrop{display:none;position:fixed;inset:0;z-index:120;background:rgba(15,23,42,.55);align-items:center;justify-content:center;padding:16px}
.avatarcrop.open{display:flex}
.avatarcrop-panel{background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-md);padding:18px;width:min(360px,92vw);display:flex;flex-direction:column;gap:14px}
.avatarcrop-title{font-weight:600;font-size:16px}
.avatarcrop-stage{position:relative;width:320px;height:320px;max-width:100%;margin:0 auto;border-radius:12px;overflow:hidden;background:var(--surface-2);touch-action:none}
.avatarcrop-stage canvas{display:block;width:320px;height:320px;cursor:grab;touch-action:none}
.avatarcrop-stage canvas:active{cursor:grabbing}
.avatarcrop-ring{position:absolute;inset:0;border-radius:50%;box-shadow:0 0 0 9999px rgba(15,23,42,.45);border:2px solid rgba(255,255,255,.9);pointer-events:none}
.avatarcrop-zoomlabel{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--text-2)}
.avatarcrop-zoom{flex:1}
.avatarcrop-actions{display:flex;justify-content:flex-end;gap:8px}

.media-card{overflow:hidden;padding:0!important}
.media-card .cover{border-radius:0}
.media-card .mc-body{padding:var(--s4) var(--s5)}

/* Learn — week card (media-card + lock scrim). Locked cards are informative, never a dead end. */
.wk-card{display:block}
.wk-card-cover{position:relative}
.wk-card-lock{position:absolute;inset:0;background:var(--navy-veil);display:grid;place-items:center;color:var(--surface)}
.wk-card-locked{opacity:.82}
.wk-card-head{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);margin-bottom:var(--s1)}
.wk-card-title{font-weight:600;font-size:16px;letter-spacing:-.01em;line-height:1.3}
.wk-card-meta{font-size:13px;color:var(--text-2);margin-top:var(--s1)}
.wk-card-locked .wk-card-meta{color:var(--text-3)}
.wk-card-upcoming{font-size:12.5px;color:var(--amber);font-weight:600;margin-top:var(--s2)}
.wk-card-tracks{font-size:12px;color:var(--text-3);margin-top:var(--s2)}

/* Experience card — the /learn landing grid and the /activities landing grid share this */
.xp-card{display:block}
.xp-card-head{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);
  flex-wrap:wrap;margin-bottom:var(--s1)}
.xp-card-title{font-weight:600;font-size:17px;letter-spacing:-.01em;line-height:1.3}
.xp-card-meta{font-size:13px;color:var(--text-2);margin-top:var(--s1)}
.xp-card-progress{display:flex;justify-content:space-between;align-items:center;gap:var(--s2);
  font-size:12px;color:var(--text-3);margin-top:var(--s3)}

/* responsive auto grids */
.grid-auto{display:grid;gap:var(--s4);grid-template-columns:1fr}
@media(min-width:560px){.grid-auto{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}}
@media(min-width:900px){.grid-auto{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}}

/* empty + error states */
.empty{text-align:center;padding:40px 20px;color:var(--text-3)}
.empty .ei{width:58px;height:58px;border-radius:17px;background:var(--surface-2);display:grid;place-items:center;margin:0 auto 14px;color:var(--text-3)}
.empty .et{font-weight:600;font-size:15.5px;color:var(--text-2);margin-bottom:4px}
.empty .es{font-size:13.5px;max-width:36ch;margin:0 auto 18px;line-height:1.5}
.errbox{background:var(--rose-wash);border:1px solid #f3c9c9;border-radius:var(--r-md);padding:13px 15px;display:flex;gap:12px;align-items:flex-start;color:#b13a3a;margin-top:12px}
.errbox .et{font-weight:600;font-size:13.5px}
.errbox .es{font-size:12.5px;margin-top:2px;color:#a85a5a}
.simtoggle{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--text-3);margin-top:10px;cursor:pointer;user-select:none}
.simtoggle input{accent-color:var(--rose)}

/* ============================================================
   FRIENDLY ERROR / STATUS PAGES (404 · 403 · 500 · generic)
   Centered card, navy→teal icon badge, status code, one CTA home.
   ============================================================ */
.errpage{min-height:calc(100vh - 200px);display:grid;place-items:center;padding:var(--s6) var(--s4)}
.errpage-card{position:relative;overflow:hidden;width:100%;max-width:540px;text-align:center;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xl);
  padding:var(--s7) var(--s5);box-shadow:var(--shadow-md)}
.errpage-card::before{content:"";position:absolute;right:-70px;top:-70px;width:210px;height:210px;
  border-radius:50%;background:radial-gradient(circle,var(--teal-wash),transparent 70%);pointer-events:none}
.errpage-ic{position:relative;width:62px;height:62px;margin:0 auto var(--s4);border-radius:19px;
  display:grid;place-items:center;color:#fff;
  background:linear-gradient(135deg,var(--navy),var(--teal));box-shadow:var(--shadow-md)}
.errpage-code{position:relative;font-size:46px;font-weight:700;line-height:1;letter-spacing:-.03em;
  color:var(--navy);margin-bottom:var(--s2)}
.errpage-title{position:relative;font-size:21px;font-weight:700;letter-spacing:-.02em;
  color:var(--text);margin-bottom:var(--s2)}
.errpage-msg{position:relative;font-size:15px;color:var(--text-2);max-width:44ch;
  margin:0 auto var(--s5);line-height:1.55}
.errpage-actions{position:relative;display:flex;flex-wrap:wrap;gap:var(--s3);justify-content:center}
.errpage-actions .btn{min-width:150px}
.errpage-note{position:relative;margin-top:var(--s4);font-size:12.5px;color:var(--text-3)}
.errpage-note code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;
  background:var(--surface-2);color:var(--text-2);padding:2px 7px;border-radius:var(--r-sm)}
@media(max-width:520px){
  .errpage-card{padding:var(--s6) var(--s4)}
  .errpage-code{font-size:40px}
}

/* directory search + filters */
.search{position:relative;margin-bottom:14px}
.search input{width:100%;border:1.5px solid var(--border-strong);border-radius:var(--r-pill);padding:12px 16px 12px 44px;font-size:14px;outline:none;transition:border-color .15s,box-shadow .15s}
.search input:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.search .si{position:absolute;left:16px;top:50%;transform:translateY(-50%);color:var(--text-3)}
.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}
.fchip{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:var(--r-pill);font-size:13px;font-weight:600;background:var(--surface-2);color:var(--text-2);transition:all .14s var(--ease);border:1.5px solid transparent}
.fchip.on{background:var(--navy);color:#fff}
.fchip:hover{border-color:var(--border-strong)}
.fchip:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.fchip-n{font-size:11px;font-weight:600;opacity:.6;font-variant-numeric:tabular-nums}

/* ============================================================
   PERSON CARDS (directory + any card roster)
   DESIGN.md §1 — members never see tables. Two arrangements from one component:
   .pc          grid  — full-bleed cover photo, name on a scrim
   .pc.pc-row   list  — side portrait, name and facts beside it
   ============================================================ */
.pc-stack{display:grid;gap:var(--s4)}
.pc-stack-grid{grid-template-columns:1fr}
@media(min-width:600px){.pc-stack-grid{grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}}
.pc-stack-list{grid-template-columns:1fr}
@media(min-width:1000px){.pc-stack-list{grid-template-columns:repeat(auto-fill,minmax(480px,1fr))}}

.pc{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-sm);overflow:hidden;display:flex;flex-direction:column;
  transition:transform .18s var(--ease),box-shadow .18s var(--ease),border-color .18s var(--ease)}
.pc:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);border-color:var(--border-strong)}

/* photo well — the clickable region */
.pc-well{position:relative;display:block;width:100%;height:180px;padding:0;overflow:hidden;
  background:var(--surface-2)}
/* Direct child only — the placeholder logo is nested inside .pc-mono and must keep its own size. */
.pc-well>img{width:100%;height:100%;object-fit:cover;object-position:center 22%;display:block}
.pc-well:focus-visible{outline:none;box-shadow:inset 0 0 0 3px var(--teal)}
.pc-tag{position:absolute;top:var(--s3);left:var(--s3);z-index:2}
/* Chip variant for use on top of a photo — opaque enough to stay legible over any image. */
.chip-glass{background:rgba(255,255,255,.94);color:var(--navy);box-shadow:var(--shadow-sm)}

/* No-photo fallback: the brand mark on a saturated gradient keyed to the person. Deliberately dark
   rather than a pale wash — the name scrim needs something to sit on, and a per-person tint reads as
   a designed placeholder instead of an avatar that failed to load. Tint comes from DirectoryMemberDto.
   Every gradient ends on a navy so the teal logo keeps its contrast wherever it lands. */
.pc-mono{display:grid;place-items:center;width:100%;height:100%;position:relative}
.pc-mono>img{width:72px;height:72px;object-fit:contain;opacity:.92;
  filter:drop-shadow(0 2px 6px rgba(15,24,48,.35))}
.pc-t1{background:linear-gradient(150deg,var(--navy-soft),var(--navy-deep))}
.pc-t2{background:linear-gradient(150deg,var(--teal-deep),var(--navy-deep))}
.pc-t3{background:linear-gradient(150deg,var(--amber),var(--navy-deep))}
.pc-t4{background:linear-gradient(150deg,var(--violet),var(--navy))}
.pc-t5{background:linear-gradient(150deg,var(--teal-press),var(--navy))}

/* name over the photo (grid variant only) */
.pc-scrim{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;
  padding:var(--s4) var(--s4) var(--s3);text-align:left;
  background:linear-gradient(to top,rgba(15,24,48,.9) 0%,rgba(15,24,48,.45) 42%,rgba(15,24,48,0) 78%)}
.pc-scrim-name{color:#fff;font-size:18px;font-weight:600;letter-spacing:-.02em;line-height:1.2}
.pc-scrim-role{color:rgba(255,255,255,.82);font-size:12.5px;line-height:1.35;margin-top:2px;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

.pc-body{padding:var(--s4) var(--s5) var(--s5);display:flex;flex-direction:column;flex:1}
.pc-name{font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.25}
.pc-role{font-size:13px;color:var(--text-2);line-height:1.4;margin-top:2px;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* labelled facts — a <dl>, so a screen reader reads "Cohort: Fall 2029" rather than two loose strings */
.pc-facts{display:flex;flex-direction:column;gap:7px;margin:0}
/* In the grid variant the facts are the body's first child and need no divider; in the list variant
   they follow the name/role, so the adjacent-sibling match adds the rule only there. */
.pc-name+.pc-facts,.pc-role+.pc-facts{margin-top:var(--s3);padding-top:var(--s3);
  border-top:1px solid var(--border)}
.pc-fact{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);font-size:12.5px}
.pc-fact dt{color:var(--text-3);flex:none}
.pc-fact dd{color:var(--text-2);font-weight:500;text-align:right;min-width:0;margin:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A chip has its own box, so the row centres on it instead of trying to sit a pill on the text
   baseline, and the dd drops the ellipsis clamp that would clip the pill's right edge. */
.pc-fact-chip{align-items:center}
.pc-fact-chip dd{overflow:visible;display:flex;justify-content:flex-end}
.pc-fact-chip .chip{padding:2px 9px;font-size:11px}

.pc-acts{display:flex;gap:var(--s2);margin-top:var(--s4)}
.pc-act{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:38px;
  padding:0 var(--s3);border-radius:var(--r-pill);font-size:13px;font-weight:600;flex:1;
  color:var(--text-2);background:var(--surface-2);
  transition:background .14s var(--ease),color .14s var(--ease)}
.pc-act:hover{background:var(--surface-3);color:var(--text)}
.pc-act:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}
.pc-act-pri{background:var(--teal-wash);color:var(--teal-deep)}
.pc-act-pri:hover{background:rgba(22,184,166,.18);color:var(--teal-deep)}
.pc-act-ic{flex:none;width:38px;padding:0}
.pc-chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center;justify-content:center;margin-top:var(--s2)}
.pc-chips .chip{padding:2px 9px;font-size:11px}

/* list variant — portrait column beside the facts */
.pc-row{flex-direction:row;align-items:stretch}
/* The well stretches to the row's height (flex default), so its contents are positioned rather than
   sized — a percentage height against an auto-height parent would collapse. */
.pc-row .pc-well{width:170px;height:auto;flex:none}
.pc-row .pc-well>img{position:absolute;inset:0;width:100%;height:100%}
.pc-row .pc-mono{position:absolute;inset:0}
.pc-row .pc-mono>img{width:58px;height:58px}
.pc-row .pc-body{flex:1;padding:var(--s4) var(--s5);min-width:0}
@media(max-width:560px){
  .pc-row{flex-direction:column}
  .pc-row .pc-well{width:100%;height:180px}
  .pc-row .pc-well>img,.pc-row .pc-mono{position:static}
}

/* directory toolbar: member count left, layout toggle right */
.dir-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s4)}
.dir-bar .dir-count{margin-bottom:0}
.vtoggle{display:inline-flex;gap:2px;padding:3px;border-radius:var(--r-pill);background:var(--surface-2);flex:none}
.vtoggle-seg{display:grid;place-items:center;width:34px;height:30px;border-radius:var(--r-pill);
  color:var(--text-3);transition:background .14s var(--ease),color .14s var(--ease)}
.vtoggle-seg:hover{color:var(--text-2)}
.vtoggle-seg.on{background:var(--surface);color:var(--navy);box-shadow:var(--shadow-sm)}
.vtoggle-seg:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}

/* Result count + load-more row, shared by the directory and the Activities list */
.dir-count,.act-count{font-size:12.5px;color:var(--text-3);margin-bottom:var(--s3)}
.dir-more,.act-more{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s4)}
.dir-more .btn,.act-more .btn{flex:1;min-width:180px}

/* Faculty cohort-management filters. Up to three chip rows stack, each labelled, so a row of
   cohort names is never mistaken for a row of statuses. */
.dir-filters{display:flex;flex-direction:column;gap:var(--s3);margin:var(--s4) 0}
.dir-filter-row{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}
.dir-filter-label{font-size:11.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text-3);flex:none;min-width:64px}
.dir-filter-row .filters{margin:0}

/* ============================================================
   PROFILE MODAL (directory detail)
   Deliberately has no avatar or monogram — with nothing competing, the name takes the size, which
   is what the reader opened the dialog to confirm. Uses Modal's Padded=false + SlimHead=true.
   ============================================================ */
.pm-pos{flex:1;font-size:12px;color:var(--text-3);font-variant-numeric:tabular-nums;min-width:0}
.pm-nav{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;color:var(--text-2);
  transition:background .14s var(--ease),color .14s var(--ease);flex:none}
.pm-nav:hover:not(:disabled){background:var(--surface-2);color:var(--text)}
.pm-nav:disabled{opacity:.3;cursor:not-allowed}
.pm-nav:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}

.pm-head{padding:var(--s5) var(--s6);border-bottom:1px solid var(--border);flex:none}
.pm-name{font-size:26px;font-weight:700;letter-spacing:-.02em;line-height:1.15}
.pm-role{font-size:14.5px;color:var(--text-2);margin-top:3px;line-height:1.4}
.pm-chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-top:var(--s3)}

/* Only this region scrolls, so the identity header and the Email action never leave the screen. */
/* minmax(0,…) + min-width:0 on the column: without them a long unbreakable value (an email, a
   full experience name) sets the track's automatic minimum and starves the About column. */
.pm-cols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);flex:1;min-height:0;overflow:auto}
.pm-cols-single{grid-template-columns:minmax(0,1fr)}
.pm-col{padding:var(--s5) var(--s6);min-width:0}
.pm-col+.pm-col{border-left:1px solid var(--border);background:var(--surface-2)}
.pm-cols-single .pm-col{background:var(--surface)}
.pm-sect{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--text-3);margin-bottom:var(--s3)}
/* pre-wrap because bios are free text and members write paragraphs */
.pm-bio{font-size:14.5px;color:var(--text-2);line-height:1.65;white-space:pre-wrap;
  overflow-wrap:anywhere}
.pm-bio-empty{color:var(--text-3);font-style:italic;margin-top:var(--s4)}

/* copyable detail rows — the Copy button stays hidden until the row is reached for */
.pm-row{display:flex;align-items:flex-start;gap:var(--s3);padding:9px 10px;margin:0 -10px;
  border-radius:var(--r-md);transition:background .14s var(--ease);min-width:0}
.pm-row:hover{background:var(--surface-3)}
.pm-cols-single .pm-row:hover{background:var(--surface-2)}
/* svg and Copy sit on the first line; the value column is what grows when the text wraps */
.pm-row>svg{color:var(--text-3);flex:none;margin-top:14px}
.pm-rl{flex:1;min-width:0}
.pm-rk{display:block;font-size:10.5px;color:var(--text-3);letter-spacing:.05em;text-transform:uppercase}
/* Values wrap instead of ellipsing — long emails and experience names are worth reading in full. */
.pm-rv{display:block;font-size:13.5px;color:var(--text);font-weight:500;line-height:1.45;
  overflow-wrap:anywhere}
.pm-rv a{color:var(--teal-deep);font-weight:600}
.pm-copy{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 11px;
  border-radius:var(--r-pill);font-size:12px;font-weight:600;background:var(--surface);
  color:var(--text-2);flex:none;margin-top:8px;
  transition:opacity .14s var(--ease),background .14s var(--ease),color .14s var(--ease)}
/* Hide-until-hover only where hover exists — on touch it would be an invisible tap target. */
@media(hover:hover){
  .pm-copy{opacity:0}
  .pm-row:hover .pm-copy,.pm-copy:focus-visible{opacity:1}
}
.pm-copy:hover{background:var(--surface-3);color:var(--text)}
.pm-copy.done{opacity:1;background:var(--teal-wash);color:var(--teal-deep)}
.pm-cols-single .pm-copy{background:var(--surface-2)}

/* "X is a Changemakers Network Leader" — its own strip between the columns and the footer, shown
   only for flagged members. The wording is italic by spec (the <em> supplies the style). */
.pm-leader{padding:var(--s3) var(--s6);border-top:1px solid var(--border);flex:none;
  font-size:13.5px;color:var(--text-2);background:var(--surface)}

.pm-foot{padding:var(--s4) var(--s6);border-top:1px solid var(--border);display:flex;
  align-items:center;gap:var(--s3);flex:none;background:var(--surface)}
.pm-hint{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--text-3)}
.pm-hint-sep{margin:0 2px}
.kbd{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;
  padding:0 5px;border-radius:5px;background:var(--surface-2);border:1px solid var(--border-strong);
  font-size:11px;font-weight:600;color:var(--text-3)}
.pm-acts{margin-left:auto;display:flex;gap:var(--s2)}
.pm-act-ic{width:42px;padding:0;flex:none}

@media(max-width:640px){
  .pm-cols{grid-template-columns:minmax(0,1fr)}
  .pm-col+.pm-col{border-left:none;border-top:1px solid var(--border)}
  .pm-head{padding:var(--s4) var(--s5)}
  .pm-name{font-size:21px}
  .pm-col{padding:var(--s4) var(--s5)}
  .pm-leader{padding:var(--s3) var(--s5)}
  .pm-foot{padding:var(--s4) var(--s5);flex-wrap:wrap}
  .pm-acts{width:100%;margin-left:0}
  .pm-acts .btn-primary{flex:1}
}

/* tag pills (profiles + directory) */
.tagrow{display:flex;gap:8px;flex-wrap:wrap}
.tagpill{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:var(--r-pill);font-size:12.5px;font-weight:600;background:var(--surface-2);color:var(--text-2);border:1.5px solid var(--border-strong);cursor:pointer;transition:all .14s}
.tagpill.on{background:var(--teal-wash);color:var(--teal-deep);border-color:var(--teal)}
.tagpill.locked{cursor:default;background:var(--surface-3);border-style:dashed;color:var(--text-2)}
.tagpill.ro{cursor:default}

/* ============================================================
   APPLICATION SYSTEM (stepper, board, feed, disclosure)
   ============================================================ */
.stepper{display:flex;align-items:center;gap:0;margin:14px 0}
.stepper .st{display:flex;flex-direction:column;align-items:center;gap:6px;flex:1;position:relative;text-align:center}
.stepper .st .sdot{width:24px;height:24px;border-radius:50%;background:var(--surface-3);color:var(--text-3);display:grid;place-items:center;font-size:12px;font-weight:700;z-index:1;border:2px solid #fff}
.stepper .st.done .sdot{background:var(--teal);color:#fff}
.stepper .st.current .sdot{background:#fff;color:var(--teal-deep);border:2px solid var(--teal);box-shadow:0 0 0 4px var(--teal-wash)}
.stepper .st.reject .sdot{background:var(--rose);color:#fff}
.stepper .st .slbl{font-size:10.5px;font-weight:600;color:var(--text-3);line-height:1.2}
.stepper .st.done .slbl,.stepper .st.current .slbl{color:var(--text-2)}
.stepper .st .sline{position:absolute;top:11px;left:50%;width:100%;height:3px;background:var(--surface-3);z-index:0}
.stepper .st.done .sline{background:var(--teal)}
.stepper .st:last-child .sline{display:none}
.board{display:flex;gap:12px;overflow-x:auto;padding:4px 2px 14px;-webkit-overflow-scrolling:touch}
.board::-webkit-scrollbar{height:8px}.board::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:4px}
.board .col{flex:0 0 232px;background:var(--surface-2);border-radius:var(--r-lg);padding:12px;min-height:80px}
.board .col h4{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);margin-bottom:10px;display:flex;justify-content:space-between;align-items:center}
.board .col h4 .ct{background:var(--surface);border-radius:var(--r-pill);padding:1px 9px;font-size:11px;color:var(--text-3)}
.board .appcard{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:11px 13px;margin-bottom:9px;cursor:pointer;transition:transform .15s var(--ease),box-shadow .15s var(--ease),border-color .15s}
.board .appcard:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm);border-color:var(--border-strong)}
.board .appcard .an{font-weight:600;font-size:13.5px}
.board .appcard .am{font-size:11.5px;color:var(--text-3);margin-top:2px}
.feed-item{display:flex;gap:12px;padding:12px 0;border-top:1px solid var(--border)}
.feed-item:first-child{border-top:none}
.feed-item .ft{flex:1}.feed-item .fmeta{font-size:11.5px;color:var(--text-3);margin-top:1px}
.feed-item .ftext{font-size:13.5px;color:var(--text-2);margin-top:5px;line-height:1.5}
.disclose{border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden;margin-top:12px}
.disclose>summary{list-style:none;cursor:pointer;padding:13px 16px;display:flex;align-items:center;justify-content:space-between;font-weight:600;font-size:14px}
.disclose>summary::-webkit-details-marker{display:none}
.disclose>summary .caret{transition:transform .2s var(--ease);color:var(--text-3)}
.disclose[open]>summary .caret{transform:rotate(180deg)}
.disclose .dbody{padding:4px 16px 14px}
.wkline{display:flex;align-items:center;gap:10px;padding:9px 0;border-top:1px solid var(--border);font-size:13.5px}
.wkline .wl-name{flex:1;font-weight:500}
.wkline .miss{color:var(--rose);font-weight:600;font-size:12.5px}

/* ============================================================
   RIGHT-SIDE SLIDE-OVER (staff applicant quick view)
   ============================================================ */
.slideover-scrim{position:fixed;inset:0;background:rgba(15,24,48,.42);backdrop-filter:blur(2px);z-index:85;opacity:0;pointer-events:none;transition:opacity .2s var(--ease)}
.slideover-scrim.open{opacity:1;pointer-events:auto}
.slideover{position:fixed;top:0;right:0;bottom:0;width:min(460px,94vw);background:#fff;z-index:86;box-shadow:var(--shadow-lg);
  transform:translateX(102%);transition:transform .26s var(--ease);overflow-y:auto}
.slideover.open{transform:none}
.slideover-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);padding:var(--s5) var(--s5) var(--s3);
  position:sticky;top:0;background:rgba(255,255,255,.94);backdrop-filter:blur(8px);border-bottom:1px solid var(--border);z-index:1}
.slideover-head h3{font-size:18px;font-weight:600;letter-spacing:-.01em}
.slideover-body{padding:var(--s4) var(--s5) var(--s7)}

/* pipeline table status dropdown + dirty marker (staff) */
.tbl select.statussel{border:1.5px solid var(--border-strong);border-radius:8px;padding:6px 8px;font-size:12.5px;font-weight:600;background:#fff;color:var(--text)}
.tbl tr.dirty{background:var(--amber-wash)}
.tbl tr.dirty td:first-child::before{content:"●";color:var(--amber);margin-right:6px;font-size:10px}
.savebar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);padding:12px 14px;margin-bottom:14px;box-shadow:var(--shadow-sm)}
/* selected table row highlight (no ::before dot, unlike .dirty) */
.tbl tr.sel-row{background:var(--amber-wash)}

/* ============================================================
   AUTH / ACCOUNT PAGES  (split-panel: sign in / up / reset)
   ============================================================ */
.auth-page{min-height:100dvh;display:flex;flex-direction:column;
  background:linear-gradient(135deg,var(--navy-deep) 0%,var(--navy) 42%,var(--teal-deep) 100%)}
.auth-stage{flex:1;display:grid;place-items:center;padding:var(--s6)}
.auth-split{width:100%;max-width:1180px;display:grid;grid-template-columns:1fr;
  background:var(--surface);border-radius:var(--r-xl);overflow:hidden;
  /* layered "floating card" depth: contact + mid + far ambient, with a faint light edge */
  box-shadow:0 2px 6px rgba(6,10,24,.35),
             0 16px 32px -8px rgba(6,10,24,.50),
             0 44px 80px -24px rgba(6,10,24,.55),
             0 0 0 1px rgba(255,255,255,.07)}

/* left brand panel — desktop only */
.auth-aside{display:none;position:relative;overflow:hidden;padding:var(--s8) var(--s7);
  align-items:center;justify-content:center;
  background:linear-gradient(160deg,var(--navy-soft) 0%,var(--navy) 55%,var(--navy-deep) 100%)}
.auth-aside::before{content:"";position:absolute;width:420px;height:420px;border-radius:50%;
  top:-150px;right:-140px;background:radial-gradient(circle,var(--teal-wash),transparent 70%)}
.auth-aside::after{content:"";position:absolute;width:320px;height:320px;border-radius:50%;
  bottom:-130px;left:-110px;background:radial-gradient(circle,var(--violet-wash),transparent 70%)}
.auth-aside .auth-logo{position:relative;width:100%;max-width:380px;height:auto}

/* right form panel */
.auth-main{display:flex;align-items:center;justify-content:center;padding:var(--s7) var(--s5)}
.auth-card{width:100%;max-width:450px}

/* mobile logo badge — shown only when the aside is hidden */
.auth-logo-mobile{display:flex;justify-content:center;margin-bottom:var(--s6)}
.auth-logo-mobile span{display:inline-flex;padding:18px 26px;border-radius:var(--r-lg);box-shadow:var(--shadow-md);
  background:linear-gradient(160deg,var(--navy) 0%,var(--navy-deep) 100%)}
.auth-logo-mobile img{width:230px;max-width:62vw;height:auto;display:block}

.auth-title{font-size:30px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px;text-align:center}
.auth-sub{color:var(--text-2);font-size:17px;line-height:1.5;text-align:center;margin-bottom:var(--s7)}
.auth-check{display:flex;align-items:center;gap:10px;font-size:16px;color:var(--text-2);margin-bottom:var(--s5)}
.auth-check input{width:19px;height:19px;accent-color:var(--teal)}
.auth-links{display:flex;flex-direction:column;align-items:center;gap:var(--s4);
  margin-top:var(--s6);font-size:16px;text-align:center}
/* login: links stack centered on mobile, left-aligned on desktop */
@media(min-width:900px){
  .auth-links--split{align-items:stretch;text-align:left}
}

/* larger inputs / buttons on auth pages only (shared primitives stay default elsewhere) */
.auth-card .field{margin-bottom:var(--s5)}
.auth-card .field label{font-size:13.5px}
.auth-card .field input,.auth-card .field textarea,.auth-card .field select{font-size:16.5px;padding:14px 17px}
.auth-card .btn{font-size:16.5px;padding:14px 26px}

/* "Who would you like to sign in as?" — one selectable card per role, radio semantics kept
   (label wraps the input) so arrow keys and screen readers work without any JS. */
.rolepick{display:flex;flex-direction:column;gap:var(--s3);margin-bottom:var(--s6)}
.rolepick-opt{display:flex;align-items:flex-start;gap:13px;padding:15px 17px;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);
  transition:border-color .12s ease,background .12s ease,box-shadow .12s ease}
.rolepick-opt:hover{border-color:var(--teal)}
.rolepick-opt input{width:19px;height:19px;margin-top:2px;flex:none;accent-color:var(--teal)}
.rolepick-opt:has(input:checked){border-color:var(--teal);background:var(--teal-wash);box-shadow:var(--shadow-sm)}
.rolepick-opt:has(input:focus-visible){outline:2px solid var(--teal);outline-offset:2px}
.rolepick-name{display:block;font-weight:600;font-size:16px}
.rolepick-desc{display:block;color:var(--text-2);font-size:13.5px;line-height:1.5;margin-top:2px}

/* full-width consent footer */
.auth-consent{padding:var(--s5) var(--s6);text-align:center;font-size:13.5px;line-height:1.6;
  color:var(--text-on-navy);background:rgba(15,24,48,.55)}
.auth-consent a{color:#fff;text-decoration:underline}

@media(min-width:900px){
  .auth-split{grid-template-columns:1.05fr 1fr;min-height:740px}
  .auth-aside{display:flex}
  .auth-main{padding:var(--s8) var(--s7)}
  .auth-logo-mobile{display:none}
}
.logout-form{display:inline}

/* header account menu (name + avatar pill → dropdown; mock `.topnav .me`) */
.usermenu{position:relative}
.usermenu>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:var(--s2);
  padding:4px 4px 4px 12px;border-radius:var(--r-pill);background:var(--surface-2);
  font-size:13px;font-weight:500;color:var(--text)}
.usermenu>summary::-webkit-details-marker{display:none}
.usermenu>summary::marker{content:""}
.usermenu>summary:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.usermenu-name{white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis}
/* Small screens: the name would crowd the bar — collapse back to the avatar alone. */
@media(max-width:599px){
  .usermenu-name{display:none}
  .usermenu>summary{padding:4px;border-radius:50%;background:transparent}
}
.usermenu-pop{position:absolute;right:0;top:calc(100% + 8px);min-width:220px;width:max-content;max-width:min(92vw,560px);
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);box-shadow:var(--shadow-lg);padding:8px;z-index:71}
.usermenu-email{font-size:13px;color:var(--text-2);padding:8px 10px;border-bottom:1px solid var(--border);white-space:nowrap}
.usermenu-item{display:block;width:100%;text-align:left;border:none;background:none;cursor:pointer;
  padding:9px 10px;border-radius:var(--r-sm);font:inherit;font-size:14px;color:var(--text);margin-top:4px;text-decoration:none}
.usermenu-item:hover{background:var(--surface-2)}
.usermenu-sep{height:1px;background:var(--border);margin:6px 0}

/* ============================================================
   BLAZOR FRAMEWORK (validation + error boundary defaults)
   ============================================================ */
.valid.modified:not([type=checkbox]){outline:1px solid #26b050}
.invalid{outline:1px solid var(--rose)}
.validation-message{color:var(--rose)}
.blazor-error-boundary{background:#b32121;padding:1rem;color:#fff;border-radius:var(--r-md)}
.blazor-error-boundary::after{content:"An error has occurred."}

/* ============================================================
   DATE / DATE-TIME PICKERS (Kit: DatePicker, DateTimePicker, CalendarPanel)
   Type-first field + zoomable calendar popup (days → months → years).
   ============================================================ */
.dtp{position:relative;display:block;width:100%}
.dtp-field{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1.5px solid var(--border-strong);
  border-radius:var(--r-md);background:#fff;color:var(--text);font:inherit;font-size:14px;text-align:left;
  transition:border-color .15s,box-shadow .15s}
.dtp-field:hover{border-color:var(--navy-soft)}
.dtp-field.open,.dtp-field:focus-within{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.dtp-field.invalid{border-color:var(--rose,#d4587a)}
.dtp-field>.icon,.dtp-field>svg{flex:0 0 auto;color:var(--text-3)}
/* Two-class selector so the generic .field input rule can't re-border the inner input
   (same trick as .phone .phone-num). */
.dtp .dtp-input,.dtp .dtp-input:focus{flex:1;min-width:0;width:auto;border:none;box-shadow:none;background:none;
  padding:0;margin:0;color:inherit;font:inherit;font-size:14px;outline:none}
.dtp .dtp-input::placeholder{color:var(--text-3)}
.dtp-clear,.dtp-caretbtn{flex:0 0 auto;border:none;background:none;cursor:pointer;color:var(--text-3);
  font:inherit;font-size:11px;padding:2px 4px;border-radius:var(--r-sm);transition:color .12s,background .12s}
.dtp-clear:hover{color:var(--text);background:var(--surface-2)}
.dtp-caretbtn:hover{color:var(--text)}
.dtp-backdrop{position:fixed;inset:0;z-index:70}
.dtp-pop{position:absolute;z-index:71;top:calc(100% + 6px);left:0;width:300px;max-width:calc(100vw - 32px);
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  padding:14px;animation:fadeIn .16s var(--ease)}
/* Inside a modal, .modal-body's scroll would clip the absolute popup — fixed with auto insets keeps
   it at its anchor (static position) while escaping the clip. (.modal has no transform once open,
   so fixed resolves to the viewport.) */
.modal-body .dtp-pop{position:fixed;top:auto;left:auto;margin-top:6px}
.dtp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.dtp-zoom{border:none;background:none;cursor:pointer;color:var(--text);font:inherit;font-weight:600;font-size:14px;
  padding:4px 10px;border-radius:var(--r-sm);transition:background .12s}
.dtp-zoom:hover{background:var(--surface-2)}
.dtp-zoomlabel{font-weight:600;font-size:14px}
.dtp-nav{width:30px;height:30px;border:none;background:var(--surface-2);border-radius:var(--r-sm);cursor:pointer;
  color:var(--text);font-size:17px;line-height:1;transition:background .12s}
.dtp-nav:hover:not(:disabled){background:var(--surface-3)}
.dtp-nav:disabled{opacity:.35;cursor:default}
.dtp-dow{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}
.dtp-dow span{text-align:center;font-size:11px;font-weight:600;color:var(--text-3);padding:4px 0}
.dtp-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.dtp-day{height:34px;border:none;background:transparent;border-radius:var(--r-sm);cursor:pointer;color:var(--text);
  font:inherit;font-size:13px;transition:background .12s}
.dtp-day:hover:not(.empty):not(:disabled){background:var(--teal-wash)}
.dtp-day.empty{cursor:default;background:transparent}
.dtp-day:disabled{opacity:.3;cursor:default;background:transparent}
.dtp-day.today{box-shadow:inset 0 0 0 1.5px var(--navy);font-weight:600}
.dtp-day.sel{background:var(--teal);color:#fff;font-weight:600}
.dtp-day.sel:hover{background:var(--teal-deep)}
/* Month / year zoom grids */
.dtp-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.dtp-cell{height:40px;border:none;background:transparent;border-radius:var(--r-sm);cursor:pointer;color:var(--text);
  font:inherit;font-size:13px;transition:background .12s}
.dtp-cell:hover:not(:disabled){background:var(--teal-wash)}
.dtp-cell:disabled{opacity:.3;cursor:default}
.dtp-cell.today{box-shadow:inset 0 0 0 1.5px var(--navy);font-weight:600}
.dtp-cell.sel{background:var(--teal);color:#fff;font-weight:600}
.dtp-cell.sel:hover{background:var(--teal-deep)}
/* Time section (DateTimePicker): hour/minute button columns + AM/PM toggle */
.dtp-time{display:flex;align-items:stretch;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
.dtp-col{flex:1;max-height:148px;overflow-y:auto;display:flex;flex-direction:column;gap:2px;
  border:1px solid var(--border);border-radius:var(--r-sm);padding:4px;scrollbar-width:thin}
.dtp-titem{flex:0 0 auto;border:none;background:transparent;border-radius:var(--r-sm);cursor:pointer;color:var(--text);
  font:inherit;font-size:13px;padding:6px 0;transition:background .12s}
.dtp-titem:hover{background:var(--teal-wash)}
.dtp-titem.on{background:var(--teal);color:#fff;font-weight:600}
.dtp-ampm{display:flex;flex-direction:column;gap:2px;border:1px solid var(--border);border-radius:var(--r-sm);padding:4px}
.dtp-ampm button{border:none;background:transparent;color:var(--text-2);padding:8px 12px;cursor:pointer;
  font:inherit;font-size:13px;font-weight:600;border-radius:var(--r-sm);transition:background .12s}
.dtp-ampm button:hover{background:var(--surface-2)}
.dtp-ampm button.on{background:var(--navy);color:#fff}
.dtp-foot{display:flex;align-items:center;justify-content:space-between;margin-top:12px}
.dtp-today{border:none;background:none;color:var(--teal-deep);cursor:pointer;font:inherit;font-size:13px;font-weight:600;padding:4px}
.dtp-today:hover{text-decoration:underline}
.dtp-clearlink{border:none;background:none;color:var(--text-3);cursor:pointer;font:inherit;font-size:13px;font-weight:600;padding:4px}
.dtp-clearlink:hover{color:var(--text);text-decoration:underline}
.dtp-done{border:none;background:var(--navy);color:#fff;padding:8px 18px;border-radius:var(--r-pill);cursor:pointer;font:inherit;font-size:13px;font-weight:600;transition:background .12s}
.dtp-done:hover{background:var(--navy-soft)}

/* ============================================================
   TYPEAHEAD / COMBOBOX (kit component)
   ============================================================ */
.ta{position:relative;display:block;width:100%}
.ta-field{display:flex;align-items:center;border:1.5px solid var(--border-strong);border-radius:var(--r-md);background:#fff;
  transition:border-color .15s,box-shadow .15s}
.ta-field.open{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.ta-input{flex:1;min-width:0;border:none;background:transparent;padding:10px 12px;font:inherit;font-size:14px;color:var(--text);outline:none}
.ta-btn{border:none;background:none;cursor:pointer;color:var(--text-3);font-size:13px;padding:0 12px;align-self:stretch;line-height:1}
.ta-btn:hover{color:var(--text)}
.ta-pop{position:absolute;z-index:71;top:calc(100% + 4px);left:0;width:100%;max-height:240px;overflow-y:auto;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);box-shadow:var(--shadow-lg);
  padding:4px;animation:fadeIn .14s var(--ease)}
.ta-opt{display:block;width:100%;text-align:left;border:none;background:none;cursor:pointer;padding:9px 12px;
  border-radius:var(--r-sm);font:inherit;font-size:14px;color:var(--text)}
.ta-opt:hover{background:var(--teal-wash)}
.ta-opt.sel{background:var(--teal);color:#fff;font-weight:600}
.ta-empty{padding:10px 12px;color:var(--text-3);font-size:13px}

/* ---------- Checkbox multi-select (CheckboxMultiSelect kit component) ----------
   Reuses the .ta / .ta-field / .ta-pop shells; adds a sticky in-popup search box and checkbox rows.
   The field shows only a count, so its height — and the popup's anchor — never moves. */
.cms{display:block;width:100%}
.cms-field{cursor:pointer;padding-left:12px}
.cms-field.disabled{opacity:.6;cursor:not-allowed;background:var(--surface-2)}
.cms-ph,.cms-sum{flex:1;min-width:0;padding:10px 0;font-size:14px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cms-ph{color:var(--text-3)}
.cms-sum{color:var(--text);font-weight:600}
.cms-pop{display:flex;flex-direction:column;max-height:320px;overflow:hidden;padding:0}
.cms-search{flex:none;display:flex;align-items:center;gap:8px;padding:8px;
  border-bottom:1px solid var(--border);background:var(--surface)}
.cms-search-in{flex:1;min-width:0;border:1.5px solid var(--border-strong);border-radius:var(--r-sm);
  background:#fff;padding:8px 10px;font:inherit;font-size:14px;color:var(--text);outline:none;
  transition:border-color .15s,box-shadow .15s}
.cms-search-in:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.cms-clear{flex:none;border:none;background:none;cursor:pointer;color:var(--teal);font:inherit;
  font-size:12px;font-weight:600;padding:4px 6px;white-space:nowrap}
.cms-clear:hover{text-decoration:underline}
.cms-list{flex:1;min-height:0;overflow-y:auto;padding:4px}
.cms-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;border:none;background:none;
  cursor:pointer;padding:8px 10px;border-radius:var(--r-sm);font:inherit;font-size:14px;color:var(--text)}
.cms-opt:hover{background:var(--teal-wash)}
.cms-opt.on{background:var(--teal-wash);font-weight:600}
.cms-box{flex:none;display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;
  border:1.5px solid var(--border-strong);border-radius:4px;background:#fff;
  font-size:11px;line-height:1;color:#fff}
.cms-opt.on .cms-box{background:var(--teal);border-color:var(--teal)}
.cms-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cms-foot{flex:none;padding:8px 12px;border-top:1px solid var(--border);background:var(--surface);
  font-size:12px;color:var(--text-3)}

/* ---------- Action menu (ActionMenu kit component) ----------
   One "Actions ▾" trigger in place of a row of per-record buttons. The popup is floated
   position:fixed by Typeahead.js (align:end), so these top/right values only apply pre-JS. */
.am{position:relative;display:inline-block}
.am-btn{display:inline-flex;align-items:center;gap:7px;border:1.5px solid var(--border-strong);
  background:transparent;color:var(--text);border-radius:var(--r-pill);padding:8px 16px;cursor:pointer;
  font:inherit;font-size:13px;font-weight:600;white-space:nowrap;
  transition:border-color .15s,box-shadow .15s,background .15s var(--ease)}
.am-btn:hover{background:var(--surface-2)}
.am-btn.open{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.am-btn:disabled{opacity:.55;cursor:not-allowed}
.am-caret{font-size:11px;line-height:1;color:var(--text-3)}
/* Fixed and hidden from the first paint, not absolute-then-fixed. The menu renders inside the
   ListView's .tbl-scroll, whose overflow-x:auto also computes overflow-y to auto — so an absolutely
   positioned popup taller than the row it drops out of counts toward that box's scrollable overflow
   and pops a vertical scrollbar onto the grid, which vanishes again the moment Typeahead.js switches
   it to fixed. On Blazor Server that round trip is long enough to see: the flicker was the grid
   gaining and losing a scrollbar. A fixed popup never contributes to an ancestor's overflow at all,
   and visibility stays hidden until position() has anchored it, so it can't flash at the wrong spot
   on the way. position() adds .pop-placed once the first placement is done. */
.am-pop{position:fixed;visibility:hidden;z-index:71;min-width:190px;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);
  box-shadow:var(--shadow-lg);padding:4px}
.am-pop.pop-placed{visibility:visible;animation:fadeIn .14s var(--ease)}
.am-item{display:block;width:100%;text-align:left;border:none;background:none;cursor:pointer;
  padding:9px 12px;border-radius:var(--r-sm);font:inherit;font-size:14px;color:var(--text);white-space:nowrap}
.am-item:hover{background:var(--teal-wash)}
.am-item.danger{color:#d84a4a}
.am-item.danger:hover{background:var(--rose-wash)}
.am-item:disabled{opacity:.5;cursor:not-allowed;background:none}
/* Divides a menu carrying two kinds of action — what to do with the record, and what to change it to. */
.am-sep{height:1px;background:var(--border);margin:5px 0}

/* ============================================================
   STAFF FORMS (events / stipends)
   ============================================================ */
.ev-in{width:100%;border:1.5px solid var(--border-strong);border-radius:var(--r-md);padding:10px 12px;font:inherit;font-size:14px;color:var(--text);background:#fff;outline:none;transition:border-color .15s,box-shadow .15s}
.ev-in:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.ev-seg{display:inline-flex;border:1.5px solid var(--border-strong);border-radius:var(--r-sm);overflow:hidden;width:fit-content}
.ev-seg button{border:none;background:#fff;color:var(--text-2);padding:8px 14px;cursor:pointer;font:inherit;font-size:13px;font-weight:600}
.ev-seg button.on{background:var(--navy);color:#fff}
.ev-check{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--text-2)}

/* ============================================================
   DISCUSSIONS / INBOX
   ============================================================ */
.disc-reply{margin-top:12px;padding-top:12px;padding-left:14px;border-top:1px solid var(--border);border-left:3px solid var(--border-strong)}
.msg-dot{width:8px;height:8px;border-radius:50%;background:var(--teal);flex:0 0 auto}

/* ---- Threaded posts (Kit ThreadList / ThreadPost) — cohort discussion + study reflection boards ----
   Depth 0 is the card body; depth 1 indents under a rule line; depth 2 indents under its parent reply.
   Indentation is a visual aid only — DOM order reads the thread linearly. Faculty / staff voice is a
   TEXT badge; the tint and left rule only reinforce it. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.avatar.xs{width:22px;height:22px;font-size:10px}
.tp{min-width:0}
.tp-head{display:flex;align-items:flex-start;gap:10px}
.tp-who{min-width:0;flex:1}
.tp-name{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-weight:600;font-size:14.5px}
.tp-badge{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:2px 7px;border-radius:var(--r-pill);
  background:var(--amber-wash);color:var(--amber-deep)}
.tp-staff .tp-badge{background:var(--teal-wash);color:var(--teal-deep)}
.tp-you{font-size:11px;font-weight:600;color:var(--text-3);padding:1px 6px;border:1px solid var(--border);border-radius:var(--r-pill)}
.tp-meta{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:12px;color:var(--text-3);margin-top:2px}
.tp-meta > *+*::before{content:"·";margin-right:10px;color:var(--border-strong)}
.tp-answers{color:var(--teal-deep);font-weight:600}
.tp-week{margin-left:auto;flex:0 0 auto}
.tp-body{margin:10px 0 0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:14.5px;line-height:1.55}
.tp-d1 .tp-body,.tp-d2 .tp-body{font-size:14px;margin-top:6px}
.tp-tomb{margin:8px 0 0;font-size:13.5px;font-style:italic;color:var(--text-3)}
.tp-reason{margin:4px 0 0;font-size:12.5px;color:var(--amber-deep)}
.tp-actions{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:13px}
.tp-actions .linkbtn{font-size:13px}
.tp-danger{color:var(--text-3)}
.tp-danger:hover{color:#b42318}
.tp-compose{display:flex;flex-direction:column;gap:8px;margin-top:10px}
.tp-compose-actions{display:flex;gap:8px}
.tp-toggle{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:12px;padding:6px 8px;border:0;border-radius:var(--r-sm);
  background:transparent;font:inherit;font-size:13px;font-weight:600;color:var(--teal-deep);cursor:pointer;text-align:left}
.tp-toggle:hover{background:var(--surface-2)}
.tp-toggle:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.tp-toggle-ico{width:12px;color:var(--text-3)}
.tp-faces{display:inline-flex;margin-left:4px}
.tp-faces .avatar{margin-left:-6px;border:2px solid #fff}
.tp-faces .avatar:first-child{margin-left:0}
.tp-last{font-weight:500;color:var(--text-3)}
.tp-replies{display:flex;flex-direction:column;gap:12px;margin-top:10px}
.tp-d0 > .tp-replies{padding-left:16px;border-left:2px solid var(--border)}
.tp-d1 > .tp-replies{padding-left:14px;margin-left:8px;border-left:2px solid var(--border)}
.tp-d1,.tp-d2{padding:10px 12px;border-radius:var(--r-md)}
.tp-d1.tp-faculty,.tp-d2.tp-faculty,.tp-d0.tp-faculty{background:var(--amber-wash);border-left:3px solid var(--amber)}
.tp-d1.tp-staff,.tp-d2.tp-staff,.tp-d0.tp-staff{background:var(--teal-wash);border-left:3px solid var(--teal)}
.tp-d0.tp-faculty,.tp-d0.tp-staff{padding:12px 14px;border-radius:var(--r-md)}
.tp-noreplies{display:flex;align-items:center;gap:12px;margin-top:12px;font-size:13px}
.tp-pinned{margin-bottom:var(--s4)}
.tp-pinned .eyebrow{margin-bottom:8px}
.tp-pinned .tp-card{box-shadow:0 0 0 2px var(--teal-wash)}
@media (prefers-reduced-motion: no-preference){
  .tp-replies{animation:tp-in .18s var(--ease)}
  @keyframes tp-in{from{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}
}
/* Below ~900px the rail moves under the board, indents shrink, and threads default collapsed above one
   reply (the Compact flag on ThreadList). At 200% text size indentation gives way before the text does. */
@media (max-width:900px){
  .tp-d0 > .tp-replies{padding-left:12px}
  .tp-d1 > .tp-replies{padding-left:8px;margin-left:0}
  .tp-d1,.tp-d2{padding:8px 10px}
}

/* ---- Study page: material + composer on the left, rail on the right ---- */
.sb-layout{display:grid;gap:var(--s4);grid-template-columns:minmax(0,1fr);margin-top:var(--s4);align-items:start}
@media (min-width:1000px){.sb-layout{grid-template-columns:minmax(0,1fr) 296px}}
.sb-rail{display:flex;flex-direction:column;gap:var(--s4);position:sticky;top:76px}
@media (max-width:999px){.sb-rail{position:static}}
.sb-material-head{display:flex;align-items:center;gap:10px;width:100%;border:0;background:transparent;font:inherit;text-align:left;cursor:pointer;padding:0}
.sb-material-head h2{font-size:17px;font-weight:600;margin:0;flex:1}
.sb-material-head .sb-caret{color:var(--text-3);transition:transform .15s var(--ease)}
.sb-material-head[aria-expanded="true"] .sb-caret{transform:rotate(90deg)}
.sb-material-body{margin-top:var(--s3);display:flex;flex-direction:column;gap:var(--s3)}
.sb-hint{font-size:13px;color:var(--text-2);margin:0 0 6px}
.sb-consequence{font-size:12.5px;color:var(--text-3);margin:6px 0 0}
.sb-block{font-size:13px;color:var(--amber-deep);margin:0}
.sb-locked{position:relative;overflow:hidden}
.sb-locked-lines{display:flex;flex-direction:column;gap:10px;margin-top:var(--s3)}
.sb-locked-line{height:12px;border-radius:6px;background:var(--surface-2);filter:blur(2px)}
.sb-locked-line.w1{width:92%}.sb-locked-line.w2{width:78%}.sb-locked-line.w3{width:85%}.sb-locked-line.w4{width:60%}
.sb-locked-copy{display:flex;flex-direction:column;gap:6px;margin-top:var(--s3);font-size:13.5px;color:var(--text-2)}
.sb-count{font-size:15px;font-weight:600;color:var(--text)}
.sb-controls{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin:var(--s4) 0 var(--s3)}
.sb-controls h2{font-size:17px;font-weight:600;margin:0;flex:1}
.sb-more{display:flex;justify-content:center;margin-top:var(--s4)}
.sb-guidelines{font-size:13.5px;color:var(--text-2);margin:0;display:flex;flex-direction:column;gap:8px}
.sb-guidelines p{margin:0}
.sb-done{display:flex;flex-direction:column;gap:4px}
.sb-done-list{margin:6px 0 0;padding-left:18px;font-size:13.5px;color:var(--text-2)}
.sb-done-list li{margin:2px 0}
.sb-status{display:flex;align-items:center;gap:8px;font-size:13.5px}
.sb-back{display:inline-block;font-size:13px;margin-bottom:var(--s2)}
.sb-roster-head{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}
.sb-roster-head h2{font-size:15px;font-weight:600;margin:0;flex:1}
.sb-roster .bar{max-width:none;margin-top:var(--s3)}
.sb-roster-names{list-style:none;margin:var(--s3) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.sb-roster-names[hidden]{display:none}
.sb-roster-names li{padding:4px 11px;border-radius:var(--r-pill);background:var(--surface-2);font-size:13px;font-weight:600;color:var(--text)}
.sb-roster-note{font-size:12.5px;color:var(--text-3);margin:var(--s3) 0 0}
.segctl{display:inline-flex;gap:2px;padding:3px;border-radius:var(--r-pill);background:var(--surface-2);flex:none}
.segctl-seg{display:inline-flex;align-items:center;gap:6px;min-height:30px;padding:0 14px;border:1.5px solid transparent;border-radius:var(--r-pill);
  background:transparent;color:var(--text-2);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:background .14s var(--ease),color .14s var(--ease)}
.segctl-seg:hover{color:var(--text)}
.segctl-seg.on{background:var(--navy);color:var(--text-on-navy)}
.segctl-seg:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.segctl-tick{font-size:11px}
.fis-loading{margin-top:var(--s4)}
.fis-empty{margin-top:var(--s4)}
.fis-week{margin-top:var(--s5)}
.fis-week-title{margin:0 0 var(--s2)}
.fis-row{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;padding:var(--s3) var(--s4);border-top:1px solid var(--border)}
.fis-row:first-child{border-top:0}
.fis-main{flex:1;min-width:200px}
.fis-title{font-weight:600;color:var(--text)}
.fis-meta{font-size:12.5px}
.fis-counts{text-align:right;font-size:13px}
.fis-cohort{font-weight:600;color:var(--text)}
.fis-all{font-size:12px}
.fis-row.is-closed .fis-title{color:var(--text-3)}
.fis-choices{margin-top:var(--s4)}
.fis-choice{display:block;font-weight:600;color:var(--text);text-decoration:none}
.lw-study-link{text-decoration:none;color:inherit}

/* Impersonation banner (staff "view as member") */
.imp-banner{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;background:var(--amber-wash);border-bottom:1px solid rgba(39,39,124,.2);padding:10px 20px}
.imp-text{font-size:14px;color:var(--navy)}
.imp-by{color:var(--text-2);font-size:12px;margin-left:4px}
.imp-form{margin:0;margin-left:auto}
.imp-stop{background:var(--amber);color:#fff;border:none;border-radius:var(--r-sm);padding:6px 12px;font-size:13px;font-weight:600;cursor:pointer}
.imp-stop:hover{opacity:.92}

/* System notices — the staff setup/health strip (Layout/SystemNotices.razor). One skinny line per open
   problem, stacked directly under the top nav in the same slot as .imp-banner. Deliberately colourless:
   these sit there for days at a time, and a coloured bar that never goes away stops being read. The
   hairline between rows is what separates several at once. */
.sysnotes{display:flex;flex-direction:column}
.sysnote{display:flex;align-items:center;gap:var(--s3);background:var(--surface);
  border-bottom:1px solid var(--border);padding:7px 20px;font-size:13px;color:var(--text-2)}
.sysnote-text{flex:1;min-width:0}
.sysnote-link{color:var(--navy);font-weight:600;margin-left:6px;text-decoration:underline;
  text-underline-offset:2px}
.sysnote-link:hover{color:var(--teal-deep)}
.sysnote-x{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:22px;height:22px;
  margin-right:-4px;border-radius:var(--r-sm);color:var(--text-3)}
.sysnote-x:hover{background:rgba(22,34,61,.07);color:var(--text)}
/* The one notice that is allowed colour, and has no dismiss control (SystemNotices.razor): the portal is
   currently NOT delivering email to the people it is addressed to. The rest of the strip stays grey so
   that this reads as different rather than as louder. */
.sysnote-critical{background:var(--rose-wash);border-bottom-color:rgba(168,50,50,.22);
  color:var(--rose-deep);font-weight:500}
.sysnote-critical .sysnote-link{color:var(--rose-deep)}
.sysnote-critical .sysnote-link:hover{color:var(--text)}

/* Notifications hub (/staff/notifications). One row per thing that can be sent. The recipient counts
   are the loudest thing on the row on purpose — the number of people about to be emailed is the fact
   that matters, and it should be readable without opening anything. */
.nt-row{display:flex;align-items:flex-start;gap:var(--s4);flex-wrap:wrap}
.nt-main{flex:1;min-width:240px}
.nt-title{display:flex;align-items:center;gap:var(--s2);font-weight:600;flex-wrap:wrap}
.nt-counts{display:flex;gap:var(--s4);flex-wrap:wrap;margin-top:var(--s3);font-size:13px}
.nt-count strong{font-size:15px;color:var(--text)}
.nt-count-muted{color:var(--text-2)}
.nt-note{margin-top:var(--s3);font-size:12.5px;color:var(--amber-deep);
  background:var(--amber-wash);border-radius:var(--r-sm);padding:6px 10px}
.nt-action{flex-shrink:0}

/* Preview dialog. The recipient list scrolls rather than truncating: staff must be able to reach the
   last name, because "how many is that really?" is the question this screen exists to answer. */
.nt-summary{font-size:14px;margin-bottom:var(--s3)}
.nt-summary strong{font-size:18px}
.nt-blocked{background:var(--rose-wash);color:var(--rose-deep);border-radius:var(--r-md);
  padding:10px var(--s3);font-size:13px}
.nt-recips{max-height:280px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--r-md)}
.nt-recip{display:flex;gap:var(--s3);align-items:baseline;padding:6px var(--s3);font-size:13px;
  border-bottom:1px solid var(--border)}
.nt-recip:last-child{border-bottom:none}
.nt-recip-nologin{background:var(--surface-2);color:var(--text-2)}
.nt-recip-name{font-weight:500;min-width:160px}
.nt-recip-mail{flex:1;min-width:0;overflow-wrap:anywhere;color:var(--text-2)}
.nt-recip-tag{flex-shrink:0;font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--rose-deep)}
.nt-sample-head{margin-top:var(--s4);font-weight:600;font-size:13px}
.nt-sample-subject{margin-top:4px;font-weight:600;font-size:13.5px}
.nt-sample{margin-top:var(--s2);max-height:240px;overflow:auto;background:var(--surface-2);
  border-radius:var(--r-md);padding:var(--s3);font-size:12.5px;white-space:pre-wrap;
  overflow-wrap:anywhere;font-family:inherit}

/* Email delivery switch (Settings -> SMTP). The current state is stated in colour before any control is
   offered, because "which radio is selected" is not the same question as "is this portal emailing
   people" on an installation whose server-side cap overrides the selection. Live is the loud one here:
   everywhere else in this app teal means good, but on this card it means real mail is going to real
   people, which is the state worth pausing over. */
.emdel-state{display:flex;flex-direction:column;gap:2px;margin-top:var(--s3);
  padding:10px var(--s3);border-radius:var(--r-md);border:1px solid transparent;font-size:13px}
.emdel-state strong{font-size:13.5px}
.emdel-state span{color:var(--text-2)}
.emdel-live{background:var(--teal-wash);border-color:rgba(22,184,166,.28);color:var(--teal-deep)}
.emdel-redirect{background:var(--amber-wash);border-color:rgba(39,39,124,.2);color:var(--amber-deep)}
.emdel-hold{background:var(--rose-wash);border-color:rgba(168,50,50,.22);color:var(--rose-deep)}

/* Star row — shared by the plenary rating page and the Kit StarRating component
   (.star-btn / .star-btn.lit are defined above). */
.stars{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.stars-sm .star-btn{font-size:17px}
.stars-ro .star-btn{cursor:default}
.star-clear{font-size:12px;font-weight:600;color:var(--text-3);margin-left:var(--s2)}
.star-clear:hover{color:var(--text-2)}
.rate-form{display:flex;flex-direction:column;gap:var(--s3)}
.rate-form-title{font-weight:600}
.rate-form .inp{margin-top:0}
.rate-form-actions{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap}
.rate-form-lead{margin:0 0 var(--s3)}

/* Staff activity feedback: the rating cell in the grid, and the per-activity feedback list. */
.rating-cell{display:flex;flex-direction:column;align-items:flex-start;gap:1px;text-align:left;
  padding:2px 6px;margin:-2px -6px;border-radius:var(--r-sm);transition:background .12s}
.rating-cell:hover{background:var(--surface-2)}
.rating-avg{font-weight:600;font-size:13.5px;color:var(--star-deep);font-variant-numeric:tabular-nums}
.rating-n{font-size:11.5px;color:var(--text-3)}
.fb-summary{display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;
  padding:var(--s3) var(--s4);background:var(--surface-2);border-radius:var(--r-md);margin-bottom:var(--s4)}
.fb-avg{display:flex;align-items:center;gap:var(--s2)}
.fb-avg-n{font-size:22px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.fb-row{padding:var(--s3) 0;border-top:1px solid var(--border)}
.fb-row:first-of-type{border-top:none}
.fb-row-head{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}
.fb-who{font-weight:600;font-size:14px}
.fb-when{margin-left:auto;font-size:12px;color:var(--text-3);white-space:nowrap}
.fb-comment{margin-top:6px;font-size:13.5px;line-height:1.55;color:var(--text-2);white-space:pre-wrap}

/* Compact form fields (activity editor, study authoring) */
.fld{display:block;font-size:12px;font-weight:600;color:var(--text-2);margin-bottom:var(--s3)}
.inp{display:block;width:100%;border:1.5px solid var(--border-strong);border-radius:var(--r-md);padding:9px 11px;font:inherit;margin-top:5px;background:var(--surface)}
.inp:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash);outline:none}

/* ---------- PHONE INPUT (Kit/PhoneInput) ---------- */
.phone{position:relative;display:flex;align-items:stretch;width:100%;margin-top:5px;
  border:1.5px solid var(--border-strong);border-radius:var(--r-md);background:var(--surface)}
.phone:focus-within,.phone.open{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.phone.is-disabled{opacity:.6}
.phone-cc{display:flex;align-items:center;gap:6px;flex:0 0 auto;cursor:pointer;font:inherit;color:var(--text);
  border:none;background:transparent;padding:9px 10px;border-right:1px solid var(--border);border-radius:var(--r-md) 0 0 var(--r-md)}
.phone-cc:hover:not(:disabled){background:var(--surface-2)}
.phone-cc:disabled{cursor:not-allowed}
.phone-flag{font-size:15px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex:0 0 22px}
.phone-dial{font-size:14px;font-weight:600;line-height:1}
.phone-caret{font-size:11px;color:var(--text-3)}
.phone .phone-num{flex:1 1 auto;min-width:0;border:none;background:transparent;font:inherit;color:var(--text);
  padding:9px 11px;margin:0;border-radius:0 var(--r-md) var(--r-md) 0}
.phone .phone-num:focus{outline:none;box-shadow:none;border:none}
.phone .phone-num:disabled{cursor:not-allowed}
.phone-backdrop{position:fixed;inset:0;z-index:70}
.phone-pop{position:absolute;z-index:71;top:calc(100% + 6px);left:0;width:320px;max-width:calc(100vw - 32px);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-md);padding:8px;overflow:hidden}
.phone-pop .phone-search{display:block;width:100%;box-sizing:border-box;font:inherit;background:var(--surface);
  border:1.5px solid var(--border-strong);border-radius:var(--r-md);padding:8px 10px;margin:0 0 8px}
.phone-pop .phone-search:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash);outline:none}
.phone-list{max-height:260px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.phone-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;cursor:pointer;font:inherit;color:var(--text);
  border:none;background:transparent;padding:8px 9px;border-radius:8px}
.phone-opt:hover{background:var(--surface-2)}
.phone-opt.sel{background:var(--teal-wash)}
.phone-opt .phone-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px}
.phone-opt .phone-optdial{flex:0 0 auto;color:var(--text-3);font-size:13px;font-variant-numeric:tabular-nums}
.phone-empty{padding:12px 9px;color:var(--text-3);font-size:13px}
.chk{display:flex;align-items:center;gap:6px;font-size:14px;font-weight:500;color:var(--text-2)}

/* ---------- RICH TEXT EDITOR (Kit/RichTextEditor, Quill snow) ---------- */
.rte{margin-top:5px}
.rte .ql-toolbar.ql-snow{border:1.5px solid var(--border-strong);border-bottom:1px solid var(--border);
  border-radius:var(--r-md) var(--r-md) 0 0;background:var(--surface-2);font-family:inherit}
.rte .ql-container.ql-snow{border:1.5px solid var(--border-strong);border-top:none;
  border-radius:0 0 var(--r-md) var(--r-md);background:var(--surface);font:inherit}
.rte .ql-editor{min-height:var(--rte-min-h,160px);font:inherit;color:var(--text);line-height:1.55}
.rte .ql-editor.ql-blank::before{color:var(--text-3);font-style:normal}
.rte:focus-within .ql-toolbar.ql-snow,
.rte:focus-within .ql-container.ql-snow{border-color:var(--teal)}
.rte:focus-within .ql-container.ql-snow{box-shadow:0 0 0 3px var(--teal-wash)}
.rte .ql-snow.ql-toolbar button:hover,.rte .ql-snow.ql-toolbar button.ql-active{color:var(--teal-deep)}
.rte .ql-snow.ql-toolbar button:hover .ql-stroke,.rte .ql-snow.ql-toolbar button.ql-active .ql-stroke{stroke:var(--teal-deep)}
.rte .ql-snow.ql-toolbar button:hover .ql-fill,.rte .ql-snow.ql-toolbar button.ql-active .ql-fill{fill:var(--teal-deep)}
.rte .ql-snow .ql-tooltip{z-index:70}

/* ---------- EMAIL TAG INPUT (send-test modal) ---------- */
.emailtags{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:5px;padding:6px 8px;
  border:1.5px solid var(--border-strong);border-radius:var(--r-md);background:var(--surface)}
.emailtags:focus-within{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.emailtags .et-chip,.picked-chips .et-chip{display:inline-flex;align-items:center;gap:6px;background:var(--surface-2);
  border:1px solid var(--border);border-radius:var(--r-pill);padding:3px 10px;font-size:13px;color:var(--text)}
.emailtags .et-chip button,.picked-chips .et-chip button{appearance:none;border:none;background:none;cursor:pointer;color:var(--text-3);
  font-size:12px;line-height:1;padding:0}
.emailtags .et-chip button:hover,.picked-chips .et-chip button:hover{color:var(--rose)}
/* Hand-picked audience chips (CampaignEditor): the chosen contacts listed under the multi-select. */
.picked-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.emailtags input{flex:1;min-width:180px;border:none;background:transparent;font:inherit;padding:6px 4px;color:var(--text)}
.emailtags input:focus{outline:none}

/* ---------- FAQ page (member-facing accordion) ---------- */
.faq-cat{font-size:15px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--navy);
  margin:var(--s6) 0 var(--s1)}
.faq-cat:first-child{margin-top:var(--s1)}
.faq-item:last-child{border-bottom:none}
.faq-item{border-bottom:1px solid var(--border)}
.faq-q{display:flex;align-items:flex-start;gap:14px;width:100%;text-align:left;background:none;border:none;
  cursor:pointer;font:inherit;font-size:15px;color:var(--text);padding:14px 2px}
.faq-q:hover span:first-child{color:var(--navy)}
.faq-q .faq-toggle{margin-left:auto;flex:0 0 auto;font-size:20px;font-weight:600;color:var(--navy);line-height:1}
.faq-a{padding:0 2px 16px;color:var(--text-2)}

/* Code of Conduct document typography (rendered inside .rte-view). */
.coc-doc h3{font-size:16px;font-weight:700;color:var(--text);margin:var(--s5) 0 var(--s2)}
.coc-doc h3:first-child{margin-top:0}
.coc-doc li{margin-bottom:6px}

/* Sign-in Code of Conduct approval gate (Layout/ConductGate): Banner header without a close X, a
   flush (Padded="false") body where the document section scrolls, and a footer row that is part of
   the flex column — so it sits hard against the modal's bottom edge with nothing showing beneath. */
.coc-gate-head{border-bottom:1px solid var(--border);padding-bottom:var(--s4)}
.coc-gate-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;padding:var(--s4) var(--s5) var(--s5);
  -webkit-overflow-scrolling:touch}
.coc-gate-sub{margin:0 0 var(--s4);font-size:14px;color:var(--text-2)}
.coc-gate-foot{flex:none;display:flex;align-items:center;gap:var(--s3);padding:var(--s4) var(--s5);
  border-top:1px solid var(--border);background:var(--surface)}
.coc-gate-note{font-size:12.5px;color:var(--text-3);margin-right:auto}

/* Read-only rendering of template HTML (matches the editor typography). */
.rte-view{font:inherit;color:var(--text);line-height:1.55}
.rte-view p{margin:0 0 .6em}
.rte-view ul,.rte-view ol{margin:0 0 .6em;padding-left:1.4em}
.rte-view a{color:var(--teal-deep)}

/* ---------- Shared ListView (search · sort · pagination) ---------- */
.lv{display:block}
.lv-bar{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s3)}
/* Sized to the input's own max-width rather than flex:1 so the optional .lv-filters slot sits beside
   the search box instead of being shoved to the far right by a stretched (but visually empty) search. */
.lv-search{flex:0 1 340px;min-width:180px}
.lv-searchinput{width:100%;max-width:340px;border:1.5px solid var(--border-strong);border-radius:var(--r-md);padding:8px 12px;font:inherit;background:var(--surface)}
.lv-searchinput:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash);outline:none}
/* Filter controls to the right of the search box. Typeaheads get a fixed width and the search box's
   tighter padding so the two line up on one row. */
.lv-filters{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
/* Separates a toolbar ACTION from the filters beside it, so a button that does something isn't read
   as a fourth thing that narrows the list. */
.tool-sep{width:1px;align-self:stretch;margin:2px 4px;background:var(--border);flex:none}
.lv-filters .ta{width:190px}
.lv-filters .ta-input{padding:8px 12px;font-size:13.5px}
.lv-filters .ta-btn{padding:0 10px}
.lv-bar-right{display:flex;align-items:center;gap:var(--s4);margin-left:auto;flex-wrap:wrap}
.lv-showing{font-size:13px;color:var(--text-2)}
.lv-perpage{font-size:13px;color:var(--text-2);display:flex;align-items:center;gap:6px}
.lv-perpage select{border:1px solid var(--border-strong);border-radius:var(--r-sm);padding:5px 8px;font:inherit;background:var(--surface)}
.lv-sortable{user-select:none;white-space:nowrap}
.lv-sortable:hover{color:var(--navy)}
.lv-sortbtn{display:inline-flex;align-items:center;padding:0;font:inherit;letter-spacing:inherit;text-transform:inherit}
.lv-sortbtn:focus-visible,.lv a.link:focus-visible{outline:2px solid var(--teal);outline-offset:2px;border-radius:var(--r-sm)}
.literaltext{display:inline-block;max-width:100%;overflow-x:auto;vertical-align:middle;white-space:pre;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:1.5;color:var(--text);
  padding:0 var(--s1);background:var(--surface-2);border:1px solid var(--border-strong);border-radius:var(--r-sm)}
.literaltext-none{font-style:italic;color:var(--text-2)}
.lv-sortarrow{font-size:11px;color:var(--text-3);margin-left:4px}
.lv-sortable.active .lv-sortarrow{color:var(--teal)}
.lv-pager{display:flex;align-items:center;gap:4px;justify-content:center;margin-top:var(--s3);flex-wrap:wrap}
.lv-pg{min-width:32px;height:32px;padding:0 8px;border:1px solid var(--border-strong);background:var(--surface);border-radius:var(--r-sm);font:inherit;font-size:13px;cursor:pointer;color:var(--text)}
.lv-pg:hover:not(:disabled){background:var(--surface-2)}
.lv-pg.active{background:var(--navy);color:#fff;border-color:var(--navy)}
.lv-pg:disabled{opacity:.4;cursor:not-allowed}
.lv-ellipsis{padding:0 4px;color:var(--text-3)}

/* Role-admin permission rows */
.permrow{display:flex;align-items:center;gap:8px;font-size:14px}
.permrow input{flex:0 0 auto}
.permkey{margin-left:auto;font-size:11px;color:var(--text-2);font-family:ui-monospace,SFMono-Regular,monospace}

/* ============================================================
   INTEGRATION SETTINGS — left tabs · test badges · SMTP accounts
   ============================================================ */
.setwrap{display:flex;gap:var(--s5);margin-top:var(--s5);align-items:flex-start}
.settabs{display:flex;flex-direction:column;gap:4px;flex:0 0 200px;position:sticky;top:140px}
.settab{display:block;width:100%;text-align:left;padding:10px 14px;border:none;background:transparent;border-radius:var(--r-sm);
  font:inherit;font-size:14px;font-weight:600;color:var(--text-2);cursor:pointer;transition:background .15s var(--ease),color .15s var(--ease)}
.settab:hover{background:var(--surface-2);color:var(--text)}
.settab.active{background:var(--teal-wash);color:var(--teal-deep)}
.setpanel{flex:1 1 auto;min-width:0}
.setpanel-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s2)}
.setpanel-head h2{font-size:18px;font-weight:700;color:var(--text)}
.setactions{display:flex;gap:8px;align-items:center;margin-top:var(--s4);flex-wrap:wrap}
.setbadge{display:inline-block;padding:3px 10px;border-radius:var(--r-pill);font-size:12px;font-weight:700;white-space:nowrap}
.badge-ok{background:var(--teal-wash);color:var(--teal-deep)}
.badge-bad{background:var(--rose-wash);color:#d84a4a}
.badge-warn{background:var(--amber-wash);color:var(--amber)}
.smtp-row{display:flex;justify-content:space-between;gap:var(--s4);align-items:flex-start;flex-wrap:wrap}
.smtp-actions{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.sfmap-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s3);margin-top:var(--s3)}
/* Optional picklist value map, sitting under its field's API name — visually secondary so the API name
   still reads as the primary control. */
.sfmap-values{margin-top:6px;font-size:12px;color:var(--text-2)}
@media (max-width:760px){.sfmap-grid{grid-template-columns:1fr}}
@media (max-width:760px){
  .setwrap{flex-direction:column}
  .settabs{flex-direction:row;flex-wrap:wrap;position:static;flex-basis:auto}
}

/* ── Global staff search (TopNav header) ─────────────────────────────── */
.gsearch{position:relative;flex:0 1 380px;max-width:380px;margin-left:var(--s2)}
.gsearch-ic{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--text-3);pointer-events:none}
.gsearch-input{width:100%;border:1.5px solid var(--border-strong);border-radius:var(--r-pill);
  padding:9px 14px 9px 40px;font-size:14px;outline:none;background:var(--surface);color:var(--text);
  transition:border-color .15s,box-shadow .15s}
.gsearch-input::placeholder{color:var(--text-3)}
.gsearch-input:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
/* Transparent full-screen catcher so a click anywhere outside closes the dropdown. */
.gs-backdrop{position:fixed;inset:0;z-index:50;background:transparent}
.gsearch-pop{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:60;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  max-height:min(70vh,460px);overflow-y:auto;padding:6px}
.gsearch-item{display:flex;align-items:center;gap:var(--s3);width:100%;text-align:left;border:none;
  background:none;cursor:pointer;padding:9px 11px;border-radius:var(--r-md)}
.gsearch-item:hover,.gsearch-item.active{background:var(--surface-2)}
.gsearch-item-main{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.gsearch-item-title{font-size:14px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gsearch-item-sub{font-size:12px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gsearch-item .chip{flex:0 0 auto}
.gsearch-empty{padding:16px;text-align:center;color:var(--text-3);font-size:13px}
@media (max-width:760px){.gsearch{display:none}}

/* ============================================================
   SYSTEM LOGS (Staff/StaffLogs) — Serilog "Logs" viewer
   ============================================================ */
.logs-toolbar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s4);margin-top:var(--s4)}
.logs-filters{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s3);flex:1 1 auto;min-width:0}
.logs-field{display:flex;flex-direction:column;gap:5px}
.logs-field > span{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--text-3)}
.logs-field.grow{flex:1 1 220px;min-width:180px}
.logs-input,.logs-select{border:1.5px solid var(--border-strong);border-radius:var(--r-md);padding:9px 12px;
  font:inherit;background:var(--surface);color:var(--text);min-height:40px}
.logs-input:focus,.logs-select:focus{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash);outline:none}
.logs-input{width:100%}
.logs-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2);margin-left:auto}
.logs-auto{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:var(--text-2);
  user-select:none;cursor:pointer;white-space:nowrap}
.logs-auto input{width:15px;height:15px;accent-color:var(--teal)}

.tbl tr.log-row{cursor:pointer}
.tbl tr.log-row:hover{background:var(--surface-2)}
.log-time{white-space:nowrap;font-size:13px;color:var(--text)}
.log-time .log-ago{display:block;font-size:11px;color:var(--text-3);font-weight:400}
.log-src{font-size:12px;color:var(--text-2);white-space:nowrap}
.log-msg{max-width:560px}
.log-msg .log-line,.log-msg .log-exc{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.log-msg .log-line{font-weight:500}
.log-msg .log-exc{font-size:11.5px;color:#d84a4a;margin-top:2px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}

/* detail modal */
.log-detail{display:flex;flex-direction:column;gap:var(--s4)}
.log-detail dl{display:grid;grid-template-columns:max-content 1fr;gap:7px var(--s4);margin:0}
.log-detail dt{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--text-3);padding-top:3px}
.log-detail dd{margin:0;font-size:14px;color:var(--text);word-break:break-word}
.log-detail dd .sub{font-size:12px}
.log-seclabel{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3);margin-bottom:6px}
.log-message{font-size:14px;color:var(--text);word-break:break-word;white-space:pre-wrap}
.log-pre{margin:0;background:var(--navy-deep);color:#e7edf8;border-radius:var(--r-md);padding:var(--s4);
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;line-height:1.55;
  white-space:pre-wrap;word-break:break-word;max-height:360px;overflow:auto}
.log-pre.json{max-height:260px}
.log-raw{margin-top:2px}
.log-raw > summary{cursor:pointer;list-style:none}
.log-raw > summary::-webkit-details-marker{display:none}

/* ============================================================
   JUMP INDEX — Staff Control "Jump to" (grouped appendix-style links)
   ============================================================ */
.jump{display:grid;gap:var(--s5) var(--s6);grid-template-columns:1fr}
@media(min-width:620px){.jump{grid-template-columns:1fr 1fr}}
@media(min-width:1000px){.jump{grid-template-columns:repeat(3,1fr)}}

.jump-group{min-width:0}
.jump-h{display:flex;align-items:baseline;gap:var(--s2);
  padding-bottom:var(--s2);margin-bottom:var(--s1);border-bottom:1px solid var(--border)}
.jump-t{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}
.jump-c{font-size:11px;font-weight:600;color:var(--text-3);opacity:.65}

.jump-list{list-style:none;margin:0;padding:0}
.jump-link{display:flex;gap:var(--s2);align-items:baseline;
  padding:6px var(--s2);margin:0 calc(var(--s2) * -1);border-radius:var(--r-sm);
  text-decoration:none;transition:background .15s var(--ease)}
.jump-link:hover{background:var(--surface-2)}
.jump-arrow{color:var(--text-3);font-weight:600;line-height:1.35;flex:0 0 auto;
  transition:transform .15s var(--ease),color .15s var(--ease)}
.jump-link:hover .jump-arrow{transform:translateX(2px);color:var(--teal-deep)}
.jump-text{display:flex;flex-direction:column;gap:1px;min-width:0}
.jump-label{color:var(--text);font-weight:600;font-size:14px;line-height:1.35}
.jump-desc{color:var(--text-3);font-size:12px;line-height:1.35}


/* ============================================================
   STAFF EXPERIENCE DETAIL / RELATED (Salesforce-style record view)
   ============================================================ */
/* Tab content body — white card surface under the tab strip. */
.dview{margin-top:var(--s4);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);box-shadow:var(--shadow-sm);padding:var(--s5)}
/* Section headings on detail/template views — clean, unboxed, with a teal accent bar. */
.dsection-head,.tpl-head{display:flex;align-items:center;gap:10px;margin:var(--s6) 0 var(--s3);
  font-size:15px;font-weight:700;color:var(--text);letter-spacing:-.01em}
.dsection-head::before,.tpl-head::before{content:"";flex:0 0 4px;width:4px;height:18px;border-radius:2px;background:var(--teal)}
.dsection-head:first-child,.tpl-head:first-child{margin-top:var(--s2)}
.dview .detail-split{margin-top:0}
.dfield{padding:8px 4px;border-bottom:1px solid var(--border);min-width:0}
.dfield label{display:block;font-size:12px;font-weight:600;color:var(--text-3);margin-bottom:2px}
.dfield .dval{font-size:14px;color:var(--text);overflow-wrap:anywhere}

/* Related-list cards (Related tab) */
/* Two columns from 1100px up, one below. The four cards are short and independent, so a single
   column wastes the width a staff screen has; 1100 is where two 300px-plus cards plus the gap stop
   squeezing the longer cohort names. */
.rel-grid{display:grid;grid-template-columns:1fr;gap:var(--s3);margin-top:var(--s4);align-items:start}
@media(min-width:1100px){.rel-grid{grid-template-columns:1fr 1fr}}

.rel-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--shadow-sm);overflow:hidden}
.rel-head{display:flex;align-items:center;gap:9px;font-weight:600;font-size:17px;color:var(--text);padding:14px 16px;border-bottom:1px solid var(--border);background:var(--surface-2)}
.rel-ico{display:inline-flex;color:var(--teal-deep)}
.rel-count{color:var(--text-3);font-weight:500}
.rel-body{display:flex;flex-direction:column}
.rel-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border)}
.rel-row:last-child{border-bottom:none}
.rel-name{font-weight:500;color:var(--text);font-size:17px;overflow-wrap:anywhere}
/* The right-hand value on a row (type, stage, link reason). A class rather than the inline 12px
   these carried, so the tab scales in one place. */
.rel-meta{color:var(--text-3);font-size:15px;white-space:nowrap}
.rel-empty{padding:16px;color:var(--text-3);font-size:16px}
.rel-viewall{padding:11px 16px;text-align:center;color:var(--teal-deep);font-size:16px;font-weight:600;border-top:1px solid var(--border)}

/* A row that goes somewhere. Rendered as <a> so it gets the browser's own affordances — middle-click,
   open in new tab, the status-bar URL — which a div with an onclick silently takes away. */
a.rel-row{text-decoration:none;color:inherit;cursor:pointer;transition:background .12s var(--ease)}
a.rel-row:hover{background:var(--teal-wash)}
a.rel-row:hover .rel-name{color:var(--teal-deep)}
a.rel-row:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}
.rel-go{color:var(--text-3);font-size:15px;flex-shrink:0}
a.rel-row:hover .rel-go{color:var(--teal-deep)}

/* ===== Public event application (Program Options + multi-step wizard) ===== */
.eapp-page{min-height:100dvh;display:flex;flex-direction:column;background:var(--navy)}
.eapp-top{display:flex;align-items:center;justify-content:space-between;padding:var(--s5) var(--s6)}
.eapp-logo{height:56px;width:auto}
.eapp-contact{color:var(--teal);font-weight:600;font-size:14px;text-decoration:none}
.eapp-contact:hover{text-decoration:underline}
.eapp-main{flex:1;display:flex;flex-direction:column;align-items:center;padding:var(--s4) var(--s5) var(--s8)}
.eapp-h1{color:#fff;font-size:44px;font-weight:700;letter-spacing:-.02em;text-align:center;margin:var(--s5) 0 var(--s4)}
.eapp-subtitle{color:var(--text-on-navy);font-size:16px;line-height:1.5;text-align:center;max-width:640px;margin:0 auto var(--s5)}

/* stepper */
.eapp-steps{display:flex;align-items:center;justify-content:center;width:100%;max-width:640px;margin:var(--s4) auto var(--s6)}
.eapp-step{flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  font-size:14px;font-weight:600;color:var(--text-on-navy);border:2px solid rgba(255,255,255,.5);background:transparent}
.eapp-step.current{background:var(--amber);border-color:var(--amber);color:#fff}
.eapp-step.done{background:rgba(255,255,255,.35);border-color:transparent;color:#fff}
.eapp-line{flex:1 1 auto;height:2px;background:rgba(255,255,255,.4);margin:0 4px}
.eapp-line.done{background:rgba(255,255,255,.7)}

/* card */
.eapp-card{width:100%;max-width:560px;background:var(--surface);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg);padding:var(--s6);margin:0 auto}
.eapp-card-title{text-align:center;font-size:26px;font-weight:700;color:var(--navy);letter-spacing:-.01em;margin:0 0 var(--s5)}
.eapp-subhead{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--amber);
  margin:var(--s5) 0 var(--s3);padding-bottom:6px;border-bottom:1px solid var(--border)}
.eapp-muted{color:var(--text-2);font-size:15px}
/* way back to /apply from the three side funnels (interest, nominate, faculty) — the shell has no nav */
.eapp-back{display:inline-block;font-size:14px;font-weight:600;color:var(--violet);margin-bottom:var(--s3)}
.eapp-back:hover{text-decoration:underline}
.eapp-prose{color:var(--text);font-size:15px;line-height:1.6;white-space:pre-line}

/* fields */
.eapp-field{margin-bottom:var(--s4)}
.eapp-field label{display:block;font-size:14px;font-weight:500;color:var(--navy);margin-bottom:6px}
.eapp-req{color:var(--violet)}
.eapp-field input,.eapp-field select,.eapp-field textarea{width:100%;border:1.5px solid var(--border-strong);
  border-radius:var(--r-sm);padding:11px 13px;font:inherit;font-size:15px;color:var(--text);background:var(--surface)}
.eapp-field textarea{resize:vertical;min-height:80px}
.eapp-field input:focus,.eapp-field select:focus,.eapp-field textarea:focus{outline:none;
  border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.eapp-field input[readonly]{background:var(--surface-2);color:var(--text-2)}
.eapp-hint{font-size:12px;color:var(--text-3);margin-top:4px}
/* inline validation: red border on the invalid field + message under it (wizard scrolls to it) */
.eapp-field.invalid input,.eapp-field.invalid select,.eapp-field.invalid textarea{
  border-color:var(--rose);box-shadow:0 0 0 3px rgba(244,63,94,.12)}
/* kit DatePicker inside a wizard field: invalid paints the dtp box, not the borderless inner input */
.eapp-field.invalid .dtp-field{border-color:var(--rose);box-shadow:0 0 0 3px rgba(244,63,94,.12)}
.eapp-field.invalid .dtp .dtp-input{box-shadow:none}
/* kit Typeahead inside a wizard field: same collision the DatePicker has above. The generic
   ".eapp-field input" rule outranks ".ta-input" on specificity, so without this the combobox gets a
   second border inside its own, its own padding and background, and width:100% on a flex child that
   crowds out the clear/caret buttons. The .ta-field wrapper already carries the border and focus ring. */
.eapp-field .ta .ta-input{width:auto;border:none;background:transparent;padding:10px 12px}
.eapp-field .ta .ta-input:focus{border:none;box-shadow:none}
.eapp-field.invalid .ta-field{border-color:var(--rose);box-shadow:0 0 0 3px rgba(244,63,94,.12)}
.eapp-field-error{color:var(--rose);font-size:12.5px;font-weight:600;margin-top:5px}
.eapp-check.invalid span{color:var(--rose)}

/* ============================================================
   Discussion reactions (Changemaker_Reaction__c)
   The values are the org's picklist, so they may be emoji, a word, or a phrase — the pill sizes to its
   content rather than assuming a single glyph.
   ============================================================ */
.reactions{display:flex;flex-wrap:wrap;gap:6px;margin-top:var(--s2)}
.reaction{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:var(--r-pill);
  border:1px solid var(--border-strong);background:var(--surface);font:inherit;font-size:13px;
  color:var(--text-2);cursor:pointer;transition:background .15s var(--ease),border-color .15s var(--ease);
}
.reaction:hover:not(:disabled){background:var(--surface-2);color:var(--text)}
.reaction.on{border-color:var(--teal);background:var(--teal-wash);color:var(--navy);font-weight:600}
.reaction:disabled{cursor:default;opacity:.75}
/* A value the org no longer offers, or one shown while the org's list is unreadable: a count, not a control. */
.reaction.is-static{cursor:default;background:var(--surface-2);border-style:dashed}
.reaction-n{font-variant-numeric:tabular-nums;font-size:12px}

/* The "somewhere else to go" card under the funnel entry: quieter than the form above it, so it reads
   as a signpost rather than a second thing to fill in. */
.eapp-card.eapp-alt{background:var(--surface-2);margin-top:var(--s4)}
.eapp-links{list-style:none;margin:var(--s2) 0 0;padding:0;display:flex;flex-direction:column;gap:8px;
  font-size:14px;color:var(--text-2)}
/* Coloured and underlined on hover, matching .eapp-message a — the shell's base rule is
   a{color:inherit;text-decoration:none}, so an anchor here would otherwise read as bold body text. */
.eapp-links a{color:var(--violet);font-weight:600}
.eapp-links a:hover{text-decoration:underline}

/* danger button (destructive confirmations, e.g. Confirm rejection) */
.btn-danger{background:var(--rose);color:#fff}
.btn-danger:hover{filter:brightness(.94)}

/* ============================================================
   APPLICATION REVIEW (staff) — the hero dialog
   Modal Banner="…" replaces the chrome header with a navy hero
   that never scrolls, so who you're deciding on stays on screen.
   Body is a two-column grid: the applicant's own words get the
   wide column, every fact drops into a quiet right rail.
   Rejecting veils the BODY ONLY — the hero stays crisp above the
   decision card — and a decision settles the modal in place
   instead of yanking it shut.
   ============================================================ */
.arv-hero{background:linear-gradient(135deg,var(--navy) 0%,#1e2f52 55%,var(--navy-soft) 100%);
  color:#fff;padding:var(--s5) var(--s5) var(--s4);position:relative;flex-shrink:0;overflow:hidden}
.arv-hero::after{content:'';position:absolute;right:-40px;top:-60px;width:220px;height:220px;border-radius:50%;
  background:radial-gradient(circle,rgba(22,184,166,.35),transparent 68%)}
.arv-hero-top{display:flex;align-items:flex-start;gap:var(--s4);position:relative;z-index:1}
.arv-id{flex:1;min-width:0}
.arv-id h2{font-size:23px;font-weight:600;letter-spacing:-.02em;color:#fff;margin-bottom:2px}
.arv-mail{font-size:13.5px;color:rgba(234,240,251,.72);overflow-wrap:anywhere}
.arv-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.arv-chip{background:rgba(255,255,255,.14);color:#fff}
.arv-readonly{background:transparent;border:1px solid rgba(255,255,255,.22);
  color:rgba(234,240,251,.7);font-weight:500;padding:6px 12px}
.arv-acts{display:flex;gap:8px;align-items:center;position:relative;z-index:1}
.arv-x{width:34px;height:34px;border-radius:50%;background:rgba(255,255,255,.13);color:#fff;
  display:grid;place-items:center;flex-shrink:0;transition:background .12s var(--ease)}
.arv-x:hover{background:rgba(255,255,255,.24)}
.btn-on-navy{background:rgba(255,255,255,.12);color:#fff;border:1px solid rgba(255,255,255,.2)}
.btn-on-navy:hover{background:rgba(255,255,255,.2)}
.arv-meta{display:flex;gap:var(--s5);flex-wrap:wrap;margin-top:var(--s4);padding-top:var(--s4);
  border-top:1px solid rgba(255,255,255,.14);position:relative;z-index:1}
.arv-meta .k{font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:rgba(234,240,251,.55)}
.arv-meta .v{font-size:14px;font-weight:500;color:#fff;margin-top:2px}

.arv-body{display:grid;grid-template-columns:1fr 300px;flex:1 1 auto;min-height:0;position:relative}
.arv-body-solo{display:block;overflow-y:auto}
.arv-main{padding:var(--s5);overflow-y:auto;min-width:0}
.arv-rail{background:var(--surface-2);border-left:1px solid var(--border);padding:var(--s5) var(--s4);overflow-y:auto}
.arv-sec{font-size:11px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--text-3);margin-bottom:var(--s3)}
.arv-q{border-left:3px solid var(--teal);padding-left:var(--s4);margin-bottom:var(--s5)}
.arv-q:last-child{margin-bottom:0}
/* History sits at the foot of the words column, inside .arv-main's scroller — never outside the grid,
   where the flush (non-scrolling) modal body would let it squeeze the answers out of reach. */
.arv-history{margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid var(--border)}
.arv-history-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3)}
.arv-history-head .arv-sec{margin-bottom:0}
.arv-history .tl{margin-top:var(--s4)}
/* Applicants paste anything — a 400-character unbroken string must wrap, not widen the dialog.
   `pre-wrap` alone won't break a word with no spaces in it; `anywhere` will. */
.arv-q h4{font-size:14.5px;font-weight:600;color:var(--navy);margin-bottom:6px;overflow-wrap:anywhere}
.arv-q p{margin:0;font-size:14.5px;color:var(--text-2);line-height:1.62;
  white-space:pre-wrap;overflow-wrap:anywhere}
.arv-bio{background:var(--surface-2);border-radius:var(--r-md);padding:var(--s4);margin-bottom:var(--s5);
  font-size:14px;color:var(--text-2);font-style:italic;white-space:pre-wrap;overflow-wrap:anywhere}
.arv-grp{margin-bottom:var(--s5)}
.arv-grp:last-child{margin-bottom:0}
.arv-kv{display:flex;justify-content:space-between;gap:var(--s3);padding:7px 0;border-bottom:1px solid var(--border);font-size:13px}
.arv-kv:last-child{border-bottom:none}
.arv-kv .k{color:var(--text-3);font-weight:500;flex-shrink:0}
.arv-kv .v{text-align:right;font-weight:500;overflow-wrap:anywhere}
.arv-check{display:flex;align-items:center;gap:9px;font-size:13px;font-weight:500;padding:6px 0}
.arv-check .b{width:19px;height:19px;border-radius:50%;display:grid;place-items:center;flex-shrink:0}
.arv-check .b.y{background:var(--teal-wash);color:var(--teal-deep)}
.arv-check .b.n{background:var(--surface-3);color:var(--text-3)}

/* reject-with-reason: a veil over the body, hero untouched above it */
.arv-veil{position:absolute;inset:0;z-index:5;background:rgba(246,248,251,.76);backdrop-filter:blur(3px);
  display:flex;justify-content:center;align-items:flex-start;padding:var(--s5);overflow-y:auto;
  animation:arv-veil-in .18s var(--ease)}
@keyframes arv-veil-in{from{opacity:0}to{opacity:1}}
.arv-rj{width:min(540px,100%);background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  overflow:hidden;animation:arv-rj-in .28s var(--ease)}
@keyframes arv-rj-in{from{opacity:0;transform:translateY(-14px) scale(.98)}to{opacity:1;transform:none}}
.arv-rj-h{display:flex;gap:var(--s3);padding:var(--s5) var(--s5) var(--s4);align-items:flex-start;
  background:linear-gradient(180deg,var(--rose-wash),var(--surface))}
.arv-rj-ic{width:38px;height:38px;border-radius:50%;background:var(--surface);color:var(--rose);
  display:grid;place-items:center;flex-shrink:0;box-shadow:0 0 0 1px rgba(247,109,109,.3)}
.arv-rj-h h3{font-size:16.5px;font-weight:600}
.arv-rj-h p{font-size:13px;color:var(--text-2);margin:3px 0 0;line-height:1.5}
.arv-rj-b{padding:0 var(--s5) var(--s4)}
.arv-lbl{font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);
  margin:var(--s4) 0 9px;display:flex;align-items:center;gap:6px}
.arv-lbl em{font-style:normal;color:var(--rose)}
.arv-lbl .opt{margin-left:auto;letter-spacing:0;text-transform:none;font-weight:500;font-size:11.5px}
.arv-rj-chips{display:flex;gap:7px;flex-wrap:wrap;padding:4px;border-radius:var(--r-md);
  transition:box-shadow .18s var(--ease)}
.arv-rj-chips.err{box-shadow:0 0 0 2px var(--rose);animation:arv-shake .3s var(--ease)}
@keyframes arv-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
.arv-rj-chip{border:1px solid var(--border-strong);background:var(--surface);border-radius:var(--r-pill);
  padding:7px 14px;font:inherit;font-size:13px;font-weight:600;color:var(--text-2);cursor:pointer;
  transition:border-color .13s var(--ease),color .13s var(--ease),background .13s var(--ease)}
.arv-rj-chip:hover{border-color:var(--rose);color:var(--rose)}
.arv-rj-chip.sel{background:var(--rose);border-color:var(--rose);color:#fff;box-shadow:0 2px 8px rgba(247,109,109,.35)}
.arv-rj-err{color:var(--rose);font-size:12px;font-weight:600;margin-top:7px}
.arv-rj-ta{width:100%;border:1px solid var(--border-strong);border-radius:var(--r-md);padding:11px var(--s3);
  font:inherit;font-size:14px;color:var(--text);background:var(--surface);resize:vertical;min-height:76px;
  transition:border-color .14s var(--ease),box-shadow .14s var(--ease)}
.arv-rj-ta::placeholder{color:var(--text-3)}
.arv-rj-ta:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.arv-rj-mail{display:flex;align-items:center;gap:11px;background:var(--surface-2);border-radius:var(--r-md);
  padding:11px var(--s4);margin-top:var(--s3);cursor:pointer;font-size:13.5px}
.arv-rj-mail input{width:17px;height:17px;accent-color:var(--teal);flex-shrink:0;cursor:pointer}
.arv-rj-mail b{font-weight:600}
.arv-rj-mail span span{display:block;font-size:12px;color:var(--text-3);margin-top:1px;overflow-wrap:anywhere}
.arv-rj-fine{font-size:12px;color:var(--text-3);margin-top:7px}
.arv-rj-f{display:flex;gap:var(--s2);justify-content:flex-end;padding:var(--s3) var(--s5);
  border-top:1px solid var(--border);background:var(--surface-2)}

/* the settled state, once a decision is recorded */
.arv-done{padding:var(--s8) var(--s5);display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:var(--s2)}
.arv-done-ring{width:76px;height:76px;border-radius:50%;display:grid;place-items:center;margin-bottom:var(--s2);
  animation:arv-pop .36s var(--ease)}
@keyframes arv-pop{from{transform:scale(.55);opacity:0}to{transform:none;opacity:1}}
.arv-done-ring.ok{background:var(--teal-wash);color:var(--teal-deep)}
.arv-done-ring.no{background:var(--rose-wash);color:#d24a4a}
.arv-done h3{font-size:21px;font-weight:600}
.arv-done p{margin:0;font-size:14px;color:var(--text-2);max-width:440px}
.arv-done-recap{display:flex;gap:7px;flex-wrap:wrap;justify-content:center;margin-top:var(--s3)}
.arv-done-row{display:flex;gap:var(--s2);margin-top:var(--s5)}

@media(max-width:899px){
  .arv-body{display:block;overflow-y:auto}
  .arv-main,.arv-rail{overflow:visible}
  .arv-rail{border-left:0;border-top:1px solid var(--border)}
  .arv-veil{position:fixed;inset:0;align-items:center;padding:var(--s4)}
  .arv-meta{gap:var(--s4)}
}

/* Review Application modal rows (staff approvals) */
.rev-row{display:flex;gap:var(--s3);padding:6px 0;border-bottom:1px solid var(--border);font-size:13.5px}
.rev-row:last-child{border-bottom:none}
.rev-l{flex:0 0 180px;color:var(--text-3);font-size:12px;font-weight:600;letter-spacing:.02em;padding-top:1px}
.rev-v{flex:1;min-width:0;overflow-wrap:anywhere}
.rev-block{padding:6px 0;border-bottom:1px solid var(--border);font-size:13.5px}
.rev-block:last-child{border-bottom:none}
.rev-block .rev-l{display:block;margin-bottom:4px}
.rev-block p{margin:0;white-space:pre-wrap}

/* requirements */
.eapp-reqs{margin:0 0 var(--s4);padding-left:20px;color:var(--text);font-size:15px;line-height:1.6}
.eapp-reqs li{margin-bottom:8px}
.eapp-check{display:flex;align-items:flex-start;gap:10px;font-size:15px;color:var(--text);cursor:pointer;margin-top:var(--s3)}
.eapp-check input{margin-top:3px;width:16px;height:16px;flex:0 0 auto}
/* The document an agreement names, when staff have given it a URL. The shell's base rule is
   a{color:inherit;text-decoration:none}, so without this it reads as ordinary label text and nobody
   discovers there is anything to open. Underlined at rest, not only on hover — it sits mid-sentence
   inside a checkbox label, where colour alone is too quiet to read as a link. */
.eapp-doclink{color:var(--violet);font-weight:600;text-decoration:underline;cursor:pointer}
.eapp-doclink:hover{color:var(--violet-deep)}

/* actions */
.eapp-actions{display:flex;gap:var(--s3);margin-top:var(--s5)}
.eapp-actions-center{justify-content:center}
.eapp-btn{appearance:none;border:none;cursor:pointer;flex:1;padding:13px 22px;border-radius:var(--r-sm);
  font:inherit;font-size:16px;font-weight:600;color:#fff;background:var(--amber);text-align:center;text-decoration:none;
  transition:filter .15s var(--ease),transform .05s var(--ease)}
.eapp-btn:hover{filter:brightness(1.08)}
.eapp-btn:active{transform:scale(.99)}
.eapp-btn:disabled{opacity:.55;cursor:not-allowed}
.eapp-btn.secondary{background:var(--surface-3);color:var(--navy)}
.eapp-actions-center .eapp-btn{flex:0 0 auto;min-width:200px}

/* error + standalone message pages */
.eapp-error{background:var(--rose-wash);border:1px solid #f3c9c9;color:#b13a3a;border-radius:var(--r-sm);
  padding:11px 13px;font-size:14px;margin-bottom:var(--s4)}
.eapp-message{width:100%;max-width:820px;margin:var(--s7) auto;text-align:center;color:var(--text-on-navy);
  font-size:20px;line-height:1.6}
.eapp-message a{color:var(--violet);text-decoration:none;font-weight:600}
.eapp-message a:hover{text-decoration:underline}

@media (max-width:560px){
  .eapp-h1{font-size:32px}
  .eapp-card{padding:var(--s5)}
  .eapp-top{padding:var(--s4)}
}
/* ===== end public event application ===== */

/* ===== global navigation loader (App.razor #nav-loader; shown and hidden by app.js) ===== */
.nav-loader{position:fixed;inset:0;z-index:6000;display:none;align-items:center;justify-content:center;
  background:rgba(246,248,251,.55); /* --bg at 55% */
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.nav-loader.show{display:flex}
.nav-loader-box{display:flex;flex-direction:column;align-items:center;gap:12px;
  background:var(--surface);border:1px solid var(--surface-3);border-radius:16px;
  padding:22px 34px;box-shadow:0 12px 40px rgba(16,34,61,.18)}
.nav-loader-spinner{width:38px;height:38px;border-radius:50%;
  border:4px solid var(--surface-3);border-top-color:var(--teal);
  animation:jcp-navspin .8s linear infinite}
.nav-loader-text{font-weight:600;font-size:14px;color:var(--navy)}
@keyframes jcp-navspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){.nav-loader-spinner{animation-duration:1.6s}}
/* ===== end global navigation loader ===== */

/* ===== reports landing cards (/staff/reports) ===== */
a.report-card{display:block;text-decoration:none;color:inherit}
a.report-card>div{height:100%;transition:box-shadow .15s ease,transform .15s ease}
a.report-card:hover>div{box-shadow:0 10px 30px rgba(16,34,61,.14);transform:translateY(-2px)}
.report-card-arrow{font-size:20px;color:var(--teal);flex-shrink:0;line-height:1.2}
/* ===== end reports landing cards ===== */

/* ===== plenary summary cards (clickable → breakdown modal) ===== */
.plenary-card{cursor:pointer;outline:none}
.plenary-card>div{height:100%;transition:box-shadow .15s ease,transform .15s ease}
.plenary-card:hover>div,.plenary-card:focus-visible>div{box-shadow:0 10px 30px rgba(16,34,61,.14);transform:translateY(-2px)}
/* ===== end plenary summary cards ===== */

/* ===== Alert — persistent inline notice (Kit/Alert.razor) =====
   Replaces the toast wherever the message is something to read and act on rather than glance at:
   it stays put until the reader dismisses it, so a long result can't scroll away mid-sentence. */
.alert{display:flex;align-items:flex-start;gap:var(--s3);border:1px solid var(--border);
  border-radius:var(--r-md);background:var(--surface);padding:var(--s3) var(--s4);
  margin-top:var(--s3);font-size:13px;color:var(--text-2)}
.alert-ico{display:flex;flex-shrink:0;margin-top:1px}
.alert-body{flex:1;min-width:0}
.alert-title{font-weight:600;margin-bottom:var(--s1)}
.alert-body p{margin:2px 0;word-break:break-word}
.alert-x{flex-shrink:0;display:flex;align-items:center;justify-content:center;
  width:26px;height:26px;margin:-2px -6px 0 0;border-radius:var(--r-sm);color:var(--text-3)}
.alert-x:hover{background:rgba(22,34,61,.07);color:var(--text)}
.alert-ok{background:var(--teal-wash);border-color:var(--teal)}
.alert-ok .alert-ico,.alert-ok .alert-title{color:var(--teal-deep)}
.alert-warn{background:var(--amber-wash);border-color:var(--amber)}
.alert-warn .alert-ico,.alert-warn .alert-title{color:var(--amber-deep)}
.alert-error{background:var(--rose-wash);border-color:var(--rose)}
.alert-error .alert-ico,.alert-error .alert-title{color:var(--rose)}
.alert-info{background:var(--surface-2);border-color:var(--border-strong)}
.alert-info .alert-ico,.alert-info .alert-title{color:var(--navy)}
/* ===== end Alert ===== */

/* ===== Sync: run history ===== */
.run-detail{margin-top:var(--s1)}
.run-detail>summary{cursor:pointer;color:var(--text-3);font-size:12px;list-style:none}
.run-detail>summary::-webkit-details-marker{display:none}
.run-detail>summary::before{content:"▸ ";transition:transform .15s var(--ease)}
.run-detail[open]>summary::before{content:"▾ "}
.run-detail>summary:hover{color:var(--text)}
.run-detail pre{margin:var(--s2) 0 0;padding:var(--s2) var(--s3);background:var(--surface-2);
  border-radius:var(--r-sm);font-family:inherit;font-size:12px;color:var(--text-2);
  white-space:pre-wrap;word-break:break-word}
/* ===== end Sync run history ===== */

/* ===== Sync: Portal vs Salesforce comparison ===== */
.cmp-obj{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);
  box-shadow:var(--shadow-sm);margin-bottom:var(--s3);overflow:hidden}
.cmp-obj>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--s3);
  padding:var(--s3) var(--s4);font-weight:600;color:var(--text)}
.cmp-obj>summary::-webkit-details-marker{display:none}
.cmp-obj>summary::before{content:"▸";color:var(--text-3);font-size:12px;transition:transform .15s var(--ease)}
.cmp-obj[open]>summary::before{transform:rotate(90deg)}
.cmp-obj>summary:hover{background:var(--surface-2)}
.cmp-obj-name{font-size:14px}
.cmp-chips{margin-left:auto;display:flex;gap:var(--s2);flex-wrap:wrap;justify-content:flex-end}
.cmp-body{padding:0 var(--s4) var(--s3);border-top:1px solid var(--border)}

/* Per-object record filter row: status chips on the left, a title search on the right. Sticky so the
   filter stays reachable while scrolling a long expanded object. */
.cmp-filter{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
  position:sticky;top:0;z-index:1;background:var(--surface);
  padding:var(--s3) 0 var(--s2);border-bottom:1px solid var(--surface-3)}
.cmp-filter .filters{margin:0;flex:1 1 auto}
.cmp-filter .cmp-search{flex:0 1 240px;margin:0}
.cmp-filter .cmp-search input{padding:8px 14px 8px 38px;font-size:13px}
.cmp-filter .cmp-search .si{left:12px}
.cmp-filter .fchip{padding:5px 12px;font-size:12px}

.cmp-note{font-size:12px;padding:0 var(--s3) var(--s3);margin:0}

.cmp-table{width:100%;border-collapse:collapse;font-size:12px;margin:0 0 var(--s2)}
.cmp-table th{text-align:left;color:var(--text-3);font-weight:600;padding:var(--s2) var(--s3);
  border-bottom:1px solid var(--border);text-transform:uppercase;font-size:10px;letter-spacing:.04em}
.cmp-table td{padding:var(--s2) var(--s3);border-bottom:1px solid var(--surface-3);vertical-align:top;
  word-break:break-word}
.cmp-table tr:last-child td{border-bottom:none}
.cmp-field{color:var(--text-2);font-weight:500;width:34%}
/* ===== end Sync comparison ===== */

/* ===== Email Log detail viewer (staff) =====
   An audit entry dressed as the email it was: envelope header, delivery outcome, then the captured
   body. HTML bodies live inside a sandboxed iframe, so nothing here reaches them and nothing of theirs
   reaches the portal — the frame's own typography is set in EmailPreviewModal.razor.cs by necessity. */
.email-view{display:flex;flex-direction:column;gap:var(--s4)}

.email-flags{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.email-channel{color:var(--text-3);font-size:12px}

.email-subject{margin:0;font-size:18px;line-height:1.35;color:var(--text);word-break:break-word}

.email-envelope{display:grid;grid-template-columns:max-content 1fr;gap:7px var(--s4);margin:0;
  padding:var(--s4);background:var(--surface-2);border-radius:var(--r-md)}
.email-envelope dt{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text-3);padding-top:3px}
.email-envelope dd{margin:0;font-size:14px;color:var(--text);word-break:break-word}
.email-envelope dd .sub{font-size:12px}

.email-error{background:var(--rose-wash);border-radius:var(--r-md);padding:var(--s3) var(--s4)}
.email-error-head{display:flex;align-items:center;gap:var(--s2);color:var(--rose);
  font-size:12px;font-weight:600;letter-spacing:.03em;text-transform:uppercase}
.email-error p{margin:var(--s2) 0 0;font-size:13px;color:var(--text);word-break:break-word}

.email-body-wrap{display:flex;flex-direction:column}
.email-seclabel{display:flex;align-items:center;gap:var(--s2);font-size:11px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--text-3);margin-bottom:6px}
.email-bodykind{font-weight:600;letter-spacing:.03em;color:var(--text-3);
  background:var(--surface-3);border-radius:var(--r-pill);padding:2px var(--s2);font-size:10px}

/* Fixed height with its own scrollbar: a stored email can be any length, and letting the frame grow
   would push the modal's own scroll past the header. */
.email-frame{width:100%;height:420px;border:1px solid var(--border);border-radius:var(--r-md);
  background:var(--surface);display:block}

.email-plain{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);
  padding:var(--s4);height:420px;overflow:auto;white-space:pre-wrap;word-break:break-word;
  font-size:14px;line-height:1.55;color:var(--text)}

.email-nobody{margin:0;padding:var(--s4);border:1px dashed var(--border-strong);
  border-radius:var(--r-md);color:var(--text-3);font-size:13px}
/* ===== end Email Log detail viewer ===== */

/* ============================================================
   STAFF LMS BUILDER — "Build the journey" (experience LMS tab)
   Week cards + completion-logic option cards, per the prototype §2.
   ============================================================ */
.lmsb-title{font-size:24px;font-weight:700;letter-spacing:-.01em;margin:2px 0 4px}

/* Week card (design "Option N"): solid navy header carrying identity + status + start date,
   white body with stacked info lines and the full action row. */
.lmsb-week{margin-bottom:var(--s3);overflow:hidden}
.lmsb-head{background:var(--navy);padding:13px 22px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.lmsb-head.locked{background:var(--navy-soft)}
.lmsb-t{font-size:16.5px;font-weight:700;color:var(--text-on-navy)}
.lmsb-date{margin-left:auto;font-size:13.5px;font-weight:600;color:rgba(234,240,251,.8)}
.lmsb-chip-live{background:var(--teal);color:var(--text-on-teal)}
.lmsb-chip-locked{background:rgba(234,240,251,.16);color:var(--text-on-navy)}
.lmsb-body{padding:13px 22px 16px}
.lmsb-line{font-size:14px;color:var(--text-2)}
.lmsb-line+.lmsb-line{margin-top:2px}
.lmsb-line b{color:var(--text);font-weight:600}
.lmsb-acts{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:14px}
.lmsb-spacer{flex:1}
.lmsb-remove{color:var(--rose)}
.lmsb-remove:hover{background:var(--rose-wash)}

/* Remove-week modal: the week being removed, called out above the consequences. */
.lmsb-remove-target{display:flex;gap:10px;align-items:center;padding:var(--s3);
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface-2)}
.lmsb-remove-ico{width:34px;height:34px;border-radius:var(--r-sm);background:var(--rose-wash);
  color:var(--rose);display:grid;place-items:center;flex-shrink:0}

.logic-head{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text-3);margin-bottom:var(--s2)}
.logic-opt{display:flex;gap:10px;align-items:flex-start;padding:var(--s3);
  border:1.5px solid var(--border-strong);border-radius:var(--r-md);margin-bottom:var(--s2);
  cursor:pointer;background:var(--surface)}
.logic-opt.on{border-color:var(--teal);background:var(--teal-wash)}
.logic-opt input{margin-top:3px;accent-color:var(--teal)}
.logic-opt .lo-t{font-weight:600;font-size:14px;display:block}
.logic-opt .lo-d{font-size:12.5px;color:var(--text-2)}

/* ============================================================
   WEEK ACTIVITIES — per-week authoring (prototype "Lesson builder · Week N")
   One card per activity, plus the week's Independent Study card. Cards carry a colored left rail:
   navy = an activity, teal = independent study.
   ============================================================ */
/* Subtitle row: the page blurb with the "Add activity" button to its right. */
.lsb-subrow{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;justify-content:space-between}
.lsb-track{margin-bottom:var(--s4);border-left:3px solid var(--navy);padding:18px 22px}
.lsb-track-study{border-left-color:var(--teal)}
.lsb-track-head{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap}
.lsb-track-head>div{flex:1;min-width:220px}
.lsb-track-t{font-size:16.5px;font-weight:700}
.lsb-track-sub{font-size:13px;color:var(--text-2);margin-top:2px}
.lsb-chips{display:inline-flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.lsb-head-acts{display:inline-flex;gap:6px;align-items:center;flex-wrap:wrap}
.lsb-none{font-size:13.5px;color:var(--text-3);margin-top:var(--s3)}
/* The activity's own blurb, under its head row — what staff wrote for fellows, so they can see what
   a card is without opening the editor. */
.lsb-act-desc{font-size:13px;color:var(--text-2);margin:var(--s3) 0 0;white-space:pre-wrap}
/* Track 3 — inline study cards (mock's study rows: uppercase .field labels, lock/required pills). */
.lsb-study{border-top:1px solid var(--border);margin-top:var(--s3);padding-top:var(--s3)}
.lsb-study-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.lsb-study-t{font-size:14px;font-weight:600;flex:1;min-width:120px}
.lsb-study-done{color:var(--teal-deep);font-weight:600}
.lsb-frow{display:flex;gap:10px;flex-wrap:wrap}
.lsb-study-summary{margin-bottom:10px}
.lsb-study-name{font-weight:600;font-size:14.5px}
.lsb-study-instr{font-size:13px;color:var(--text-2);margin-top:2px}
.lsb-study-meta{font-size:12.5px;color:var(--text-3);margin-top:4px}

/* Fellow week — independent study cards (mock §3: pick-one list + study modal embeds).
   Self-sufficient (background+radius) so the same class works inside modals without .card. */
.lw-study{width:100%;text-align:left;display:flex;gap:14px;align-items:center;padding:16px 18px;
  background:var(--surface);border-radius:var(--r-lg);border:1px solid var(--border);cursor:pointer;font:inherit}
.lw-study.done{border-color:var(--teal)}
.lw-study-ico{width:42px;height:42px;border-radius:50%;background:var(--surface-3);color:var(--text-3);
  display:grid;place-items:center;font-size:15px;font-weight:700;flex:0 0 auto}
.lw-study.done .lw-study-ico{background:var(--teal);color:#fff}
.lw-study-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.lw-study-t{font-weight:600;font-size:15px}
.lw-study-sub{font-size:13px;color:var(--text-2)}
.lw-study-rule{font-size:12px;color:var(--text-3)}
.lw-study-go{color:var(--text-3);font-size:20px;flex:0 0 auto}
.lw-embed{position:relative;aspect-ratio:16/9;border-radius:var(--r-md);overflow:hidden;background:var(--navy)}
.lw-embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.lw-embed-pdf{width:100%;height:360px;border:1px solid var(--border);border-radius:var(--r-md)}
.lw-embed-placeholder{background:var(--navy);border-radius:var(--r-md);aspect-ratio:16/9;display:grid;place-items:center}
.lw-embed-play{width:56px;height:56px;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;
  display:grid;place-items:center;font-size:20px}
.lw-embed-audio{background:var(--surface-2);border-radius:var(--r-md);padding:10px}
.lw-embed-audio audio{width:100%;display:block}

/* Journey — week modal chain (week + its activities → activity detail, or → studies → player). */
.wk-card-click{cursor:pointer}
.lwm-track{width:100%;display:flex;align-items:center;gap:12px;text-align:left;font:inherit;cursor:pointer;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);padding:14px 16px}
.lwm-track:hover{border-color:var(--teal)}
.lwm-track-off{opacity:.55;cursor:default;pointer-events:none}
.lwm-track-ico{width:38px;height:38px;border-radius:50%;background:var(--navy);color:#fff;display:grid;
  place-items:center;font-weight:700;font-size:14px;flex:0 0 auto}
.lwm-track-off .lwm-track-ico{background:var(--surface-3);color:var(--text-3)}
.lwm-track-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.lwm-track-t{font-weight:700;font-size:14.5px}
.lwm-track-sub{font-size:12.5px;color:var(--text-2)}
.lwm-track-go{color:var(--text-3);font-size:18px;flex:0 0 auto}
.lwm-foot{background:var(--surface-2);border-radius:var(--r-md);padding:10px 12px;font-size:12.5px;
  color:var(--text-2);text-align:center}
.lwm-cover{position:relative;aspect-ratio:16/9;border-radius:var(--r-lg);display:grid;place-items:center;
  color:#fff;overflow:hidden}
.lwm-cover-label{position:absolute;left:14px;bottom:10px;font-weight:700;font-size:13px;color:#fff}
.lwm-tz{background:var(--surface-2);border-radius:var(--r-md);padding:12px 14px}
.lwm-tz-head{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3)}
.lwm-tz-main{font-weight:700;font-size:15px;margin-top:4px}
.lwm-tz-sub{font-size:12.5px;color:var(--text-2)}
.lwm-going{display:flex;gap:10px;align-items:center;border:1px solid var(--teal);background:var(--teal-wash);
  border-radius:var(--r-md);padding:12px 14px;font-size:14px}
.lwm-going-ico{width:26px;height:26px;border-radius:50%;background:var(--teal);color:#fff;display:grid;
  place-items:center;font-size:13px;flex:0 0 auto}
.lwm-wait{background:var(--surface-2);border-radius:var(--r-md);padding:10px 12px;font-size:13px;
  text-align:center;color:var(--text-2)}

/* One activity, wherever a member meets it. RSVP, the going count and the join gate all belong to the
   activity (2026-08). The schedule's own answer row moved onto the meeting page (2026-09-04), taking
   .sched-act-meta and .sched-act-actions with it; the note line survives because both the meeting page
   and the one-on-one page still state "why there's no button here". .lwm-meet wraps an ActivityCard
   inside the week modal, which is why it can't be the same class — that card is itself a button. */
.sched-act-note{font-size:12.5px;color:var(--text-2)}
/* The schedule groups its cards by week — the heading is what makes a long list navigable. */
.sched-week{margin-top:var(--s4)}
.sched-week-head{display:flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap;margin-bottom:var(--s3)}
.sched-week-t{font-weight:700;font-size:15px;letter-spacing:-.01em}

/* A page heading with a control beside it — the schedules' calendar/cards toggle. */
.page-head{display:flex;align-items:flex-start;gap:var(--s4);flex-wrap:wrap;margin-bottom:var(--s5)}
.page-head-t{min-width:0;flex:1 1 320px}
.page-head .vtoggle{margin-top:var(--s4)}

/* The schedule's own card (2026-09-04). The whole card is a link to the meeting's page, so it carries
   state and context and no controls — RSVP, joining and the receipt live on the page it opens. */
.sched-card{display:block;text-decoration:none;color:inherit;padding:0;overflow:hidden}
.sched-card-body{padding:14px;display:flex;flex-direction:column;gap:5px}
.sched-card-top{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;min-height:22px}
.sched-card-top .chip{font-size:11.5px}
.sched-card-go{margin-left:auto;font-size:12px;font-weight:700;color:var(--teal);white-space:nowrap;opacity:0;transition:opacity .15s var(--ease)}
.sched-card:hover .sched-card-go,.sched-card:focus-visible .sched-card-go{opacity:1}
.sched-card-n{font-weight:700;font-size:15px;letter-spacing:-.01em;line-height:1.3}
.sched-card-w{font-size:12.5px;color:var(--text-2)}
.sched-card-m{font-size:11.5px;color:var(--text-3)}
/* The type badge over the cover — same treatment the card had before it became a link. */
.sched-card-type{position:absolute;top:10px;left:10px;background:rgba(0,0,0,.55);color:#fff;
  font-size:11px;font-weight:600;padding:3px 9px;border-radius:var(--r-pill);backdrop-filter:blur(4px)}
/* "You haven't answered yet" — an invitation, not a verdict, so it reads as the outline of a button. */
.chip-rsvp{color:var(--teal);background:var(--teal-wash);border:1.5px solid rgba(22,184,166,.3);font-weight:600}
.lwm-meet{display:flex;flex-direction:column;gap:8px;border:1px solid var(--border);
  border-radius:var(--r-lg);padding:10px;background:var(--surface-2)}
.lwm-meet-foot{display:flex;flex-direction:column;gap:8px}
/* The studies line under an activity that carries them — where the RSVP row sits on a meeting. Self-paced
   content has no room and no hour, so it shows what there is to do instead of "count me in". */
.lwm-track-hint{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.lwm-meet-count{font-size:12.5px;color:var(--text-2)}
.lwm-meet-note{background:var(--surface-3);border-radius:var(--r-md);padding:8px 10px;font-size:12.5px;
  color:var(--text-2);text-align:center}
.lsb-off{background:var(--navy);color:var(--text-on-navy)}

/* ============================================================
   CELEBRATION — completion confetti + branded badge (jcp.celebrate)
   "burst" = one item done; "strike" (.big) = the whole week done.
   ============================================================ */
.celebrate{position:fixed;inset:0;z-index:101;display:grid;place-items:center;pointer-events:none}
.celebrate-card{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg);padding:22px 36px;display:flex;flex-direction:column;align-items:center;gap:4px;
  animation:celebrate-pop .55s var(--ease) both;transition:opacity .4s ease,transform .4s ease}
.celebrate.out .celebrate-card{opacity:0;transform:translateY(-16px) scale(.94)}
.celebrate-mark{width:56px;height:56px;border-radius:16px;background:linear-gradient(135deg,var(--navy),var(--teal));
  display:grid;place-items:center;color:#fff;margin-bottom:4px}
.celebrate-mark svg{width:30px;height:30px}
.celebrate-t{font-size:23px;font-weight:700;letter-spacing:-.01em}
.celebrate-s{font-size:14px;color:var(--text-2)}
.celebrate.big .celebrate-card{padding:30px 48px}
.celebrate.big .celebrate-card{animation:celebrate-slam .65s var(--ease) both}
.celebrate.big .celebrate-mark{width:72px;height:72px;border-radius:20px}
.celebrate.big .celebrate-mark svg{width:40px;height:40px}
.celebrate.big .celebrate-t{font-size:30px}
.celebrate-rays{position:absolute;top:-54px;left:50%;width:240px;height:240px;margin-left:-120px;border-radius:50%;
  background:repeating-conic-gradient(var(--teal-wash) 0 14deg,transparent 14deg 30deg);
  animation:celebrate-spin 7s linear infinite;z-index:-1}
@keyframes celebrate-pop{0%{transform:scale(.5) rotate(-3deg);opacity:0}65%{transform:scale(1.06) rotate(1deg);opacity:1}100%{transform:scale(1) rotate(0)}}
@keyframes celebrate-slam{0%{transform:scale(2.1);opacity:0}55%{transform:scale(.94);opacity:1}75%{transform:scale(1.05)}100%{transform:scale(1)}}
@keyframes celebrate-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){
  .celebrate-card,.celebrate.big .celebrate-card{animation:none}
  .celebrate-rays{display:none}
}

/* Zoom meeting fields in the activity editor (ZOOM_INTEGRATION_PLAN §7.1). The read-only block shows
   what Zoom generated after a save — never editable, since the values come back from the API. */
.zoom-lbl{font-size:12px;font-weight:600;margin-bottom:2px;display:flex;align-items:center;gap:4px}
.zoom-note{font-size:12.5px;margin:0}
.zoom-ro{border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-2);padding:10px 12px;display:flex;flex-direction:column;gap:6px}
.zoom-ro-row{display:flex;gap:8px;align-items:baseline;font-size:13px;min-width:0}
.zoom-ro-row .sub{flex:0 0 78px;font-size:12px}
.zoom-ro-row a{color:var(--teal);overflow-wrap:anywhere;min-width:0}
.zoom-ro-row code{font-size:12.5px;background:var(--teal-wash);padding:1px 6px;border-radius:var(--r-sm)}

/* Attendance page — Zoom provenance and the unmatched-participants queue (ZOOM_INTEGRATION_PLAN §7.2).
   The minute chip exists so a staffer overriding a mark can see why Zoom decided what it decided. */
.zoom-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:var(--s3);
  border-top:1px solid var(--border);padding-top:var(--s3)}
.zoom-bar-note{font-size:12px;margin-left:auto}
.zoom-mins{font-size:12.5px;font-weight:600;padding:2px 8px;border-radius:var(--r-pill);white-space:nowrap}
.zoom-mins.ok{background:var(--teal-wash);color:var(--teal)}
.zoom-mins.under{background:var(--surface-2);color:var(--text-2)}
.zoom-edited{font-size:11px;margin-top:3px}
.zoom-actions{display:inline-flex;align-items:center;gap:10px;justify-content:flex-end}
.zoom-revert{font-size:12px}
.zoom-q-toggle{display:flex;align-items:center;gap:8px;width:100%;text-align:left;font:inherit;font-size:14px}
.zoom-q-toggle .sub{margin-left:auto;font-size:12px}
.zoom-q-help{font-size:12.5px;margin:var(--s3) 0 0}
.zoom-q-row{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
  border-top:1px solid var(--border);padding:var(--s3) 0}
.zoom-q-who{display:flex;flex-direction:column;gap:2px;min-width:180px;flex:1}
.zoom-q-name{font-weight:600;font-size:14px}
.zoom-q-who .sub{font-size:12px}
.zoom-q-act{display:flex;align-items:center;gap:8px;min-width:260px}
.zoom-q-act > :first-child{flex:1}

/* Attendance page — the activity picker inside a week. A week can hold several, so the segmented
   control has to survive both long activity names (ellipsis) and many of them (wrap), which the
   plain .ev-seg strip doesn't. */
.zoom-mtg{margin-top:var(--s4)}
.zoom-mtg .ev-seg{flex-wrap:wrap;max-width:100%}
.zoom-mtg .ev-seg button{max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* .ev-seg was drawn for two options and leans on the on/off fill alone; past two, unselected
   neighbours run together without a rule between them. */
.zoom-mtg .ev-seg button + button{border-left:1px solid var(--border-strong)}
.zoom-mtg .ev-seg button:disabled{cursor:default;opacity:.6}

/* The Zoom row and the attendance group's heading. The per-activity block these used to sit inside
   went with the move of per-meeting controls onto the meeting page (2026-09-04); what is left is used
   by the cohort-time card on the faculty schedule and by the meeting page's register. */
.zoom-mtg-name{font-size:13.5px;font-weight:600;margin-bottom:4px}
.zoom-mtg-row{margin-top:8px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.zoom-mtg-row .zoominput{flex:1;min-width:220px;padding:8px 10px;border:1px solid var(--border-strong);
  border-radius:var(--r-sm);font:inherit}
.zoom-mtg-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.zoom-mtg-head .sub{margin-left:auto;font-size:12px}

/* The two halves of a faculty week: the plenaries they attend and the meetings they run. Grouped
   under headings rather than chipped inline, because the difference decides what a facilitator can do
   once they open one — a reader scanning for "what's mine here" should be able to answer it from the
   heading and stop, instead of opening every card to find out. */
.sched-group-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:var(--s4);margin-bottom:var(--s3);
  padding-bottom:8px;border-bottom:1px solid var(--border-strong);
  font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2)}
/* The qualifier sits at the far end in sentence case: it explains the heading rather than continuing
   it, and running it in the same tracked-out caps would read as a second heading. */
.sched-group-note{margin-left:auto;font-weight:500;letter-spacing:0;text-transform:none;
  font-size:11.5px;color:var(--text-3)}

/* The when-line at the top of a meeting page. It is the one fact the schedule exists to state, and it
   has to survive the reader's clock being different from the meeting's — jcp.fillLocalTimes appends
   "· 2:00 PM your time" into the trailing span. (Replaced .sched-when 2026-09-04, when the faculty
   week blocks that used it became cards.) */
.mtg-when [data-localtime]{font-weight:400;color:var(--text-3)}
.sched-card-w [data-localtime]{color:var(--text-3)}

/* Staff programme schedule — the experience picker and cohort chips share one row on a wide screen
   and stack on a narrow one, so the chips never squeeze the select down to an unreadable width. */
.sched-controls{display:flex;gap:var(--s4);flex-wrap:wrap;align-items:flex-end;margin-top:var(--s4)}

/* Faculty attendance history — every fellow against every meeting of the active fellowship. A matrix
   rather than a list because the interesting value is the CELL: "who was missing in week 4" and "who
   has been drifting all term" are the same picture read down a column or across a row. Deliberately
   not .tbl — that is the staff list chrome, and this is a dense grid of glyphs, not rows of fields. */
.att-legend{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:var(--s3);font-size:12px;color:var(--text-2)}
.att-legend .att-key{display:inline-block;width:12px;height:12px;border-radius:3px;vertical-align:-1px;
  margin-right:5px;border:1px solid var(--border-strong);background:var(--surface)}
.att-legend .att-key.att-yes{background:var(--teal-wash);border-color:var(--teal)}
.att-legend .att-key.att-no{background:var(--rose-wash);border-color:var(--rose)}
.att-legend .sub{margin-left:auto}

/* Its own scroller. A term's worth of columns will outrun any laptop, and the page body must never
   scroll sideways to accommodate one card. */
.att-scroll{margin-top:var(--s3);overflow-x:auto;border:1px solid var(--border-strong);border-radius:var(--r-md)}
.att-matrix{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;font-size:12.5px}
.att-matrix th,.att-matrix td{padding:8px 10px;border-bottom:1px solid var(--border);text-align:center;white-space:nowrap}
.att-matrix thead th{background:var(--surface-2);font-weight:600;vertical-align:bottom;
  border-bottom:1px solid var(--border-strong);position:sticky;top:0;z-index:2}
.att-matrix thead th span{display:block;line-height:1.3}
.att-matrix .att-wk{font-size:11px;color:var(--text-3);letter-spacing:.04em}
.att-matrix .att-mtg{font-weight:600}
.att-matrix .att-when{font-size:11px;color:var(--text-3);font-weight:400}

/* The name column stays put while the meetings scroll under it — a row of ticks means nothing once
   its fellow has scrolled off the left edge. */
.att-matrix .att-name{position:sticky;left:0;z-index:3;background:var(--surface);text-align:left;
  font-weight:600;border-right:1px solid var(--border-strong);min-width:190px}
.att-matrix thead .att-name{z-index:4;background:var(--surface-2)}
/* The flex goes on an inner span, never on the cell. display:flex on a <th> pulls it out of the
   table's column layout — the browser wraps it in an anonymous cell — which un-sticks it and stops it
   sharing a width with the header cell above, i.e. exactly the failure the sticky rule prevents. */
.att-matrix tbody .att-name > .att-who{display:flex;align-items:center;gap:8px}
.att-matrix .att-total{font-variant-numeric:tabular-nums;color:var(--text-2);
  border-left:1px solid var(--border-strong);background:var(--surface-2)}
/* Hover skips the marked cells. A blanket row hover outranks .att-cell.att-yes on specificity and
   repaints the teal/rose coding away at the moment the reader is pointing at it. */
.att-matrix tbody tr:hover td:not(.att-yes):not(.att-no){background:var(--surface-2)}

.att-cell{color:var(--text-3);font-size:14px;cursor:default}
/* Same two inks the teal/rose chips use, so present-and-absent read as the palette already teaches
   them rather than as a third colour scale invented for this grid. */
.att-cell.att-yes{background:var(--teal-wash);color:var(--teal-deep);font-weight:700}
.att-cell.att-no{background:var(--rose-wash);color:#d84a4a;font-weight:700}
/* Not this fellow's meeting — a faculty member running two cohorts sees both rosters as rows, and one
   cohort's meetings are simply not the other's business. Struck out of the grid rather than left blank,
   because an empty cell already means "theirs, nobody has marked it yet" and that one is a task. */
.att-cell.att-na{background:var(--surface-2);color:var(--text-3);opacity:.55}
/* A mark the Zoom pull made is evidence; one a person ticked is judgement. The underline is what
   lets a faculty member tell the two apart while scanning, without a second colour scale. */
.att-cell.att-zoom{text-decoration:underline;text-underline-offset:3px;text-decoration-style:dotted}

/* ---- Salesforce pull drill-down (SYNC_REDESIGN_PLAN.md §5.2–5.3) ---- */
.sfdiff-field{font-weight:600}
.sfdiff-sf{background:var(--amber-wash);text-align:left}
.sfdiff-null{color:var(--text-3);font-style:italic}

/* ---- CSV backup import (SYNC_REDESIGN_PLAN.md §7b) ---- */
.sfimp-drop{display:flex;align-items:center;gap:var(--s4);padding:var(--s4);border:2px dashed var(--border);
  border-radius:var(--r-md);cursor:pointer;color:var(--text-2);transition:border-color .15s var(--ease)}
.sfimp-drop:hover{border-color:var(--teal)}
.sfimp-drop input[type=file]{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden}


/* ---- Merge-token chips (Kit MergeTokenBar) ------------------------------------------------
   Dashed border says "this is a placeholder, not a button that does something to your data";
   the monospace face makes {{first}} read as a literal you can also type by hand. */
.tokbar{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin:-4px 0 var(--s3)}
.tokbar-lbl{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}
.tokbar-hint{font-size:12px;color:var(--text-3);margin-left:2px}
.tok{appearance:none;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;font-weight:600;
  padding:4px 10px;border-radius:var(--r-sm);border:1px dashed var(--border-strong);background:var(--surface-2);
  color:var(--navy-soft);cursor:pointer;transition:.12s var(--ease)}
.tok:hover{border-color:var(--teal);border-style:solid;background:var(--teal-wash);color:var(--teal-deep)}
.tok:active{transform:scale(.96)}

/* ---- Tri-state select-all checkbox (staff grids with a checkbox column) --------------------
   app.css had no checkbox style at all before the Welcome tab; native controls vary too much
   across platforms to sit next to the rest of the kit. */
.cb{appearance:none;width:18px;height:18px;border:1.75px solid var(--border-strong);border-radius:5px;
  background:var(--surface);cursor:pointer;display:inline-grid;place-content:center;vertical-align:middle;
  margin:0;transition:.12s var(--ease)}
.cb:hover{border-color:var(--teal)}
.cb:focus-visible{outline:none;box-shadow:0 0 0 3px var(--teal-wash)}
.cb:checked,.cb:indeterminate{background:var(--teal);border-color:var(--teal)}
.cb:checked::after{content:"";width:10px;height:6px;border:2px solid #fff;border-top:0;border-right:0;
  transform:rotate(-45deg) translateY(-1px)}
.cb:indeterminate::after{content:"";width:9px;height:2px;background:#fff;border-radius:1px}
.cb:disabled{opacity:.45;cursor:not-allowed;background:var(--surface-2);border-color:var(--border)}


/* ---- Welcome + Audits tabs (Messaging) -----------------------------------------------------
   Added with the onboarding work. .savebar already existed as a light inline strip, so the bulk
   bar is a MODIFIER rather than a redefinition — changing the shared class would restyle every
   other save bar in the app. */
.savebar-bulk{position:sticky;bottom:var(--s3);z-index:40;margin-top:var(--s4);margin-bottom:0;
  background:var(--navy);border-color:var(--navy);color:var(--text-on-navy);padding:13px var(--s5);
  border-radius:var(--r-lg);box-shadow:var(--shadow-lg)}
.savebar-bulk .n{font-weight:700;font-size:14.5px}
.savebar-bulk .clr{color:#9fb0d0;font-size:13px;background:none;border:none;cursor:pointer;font:inherit;
  text-decoration:underline;padding:0}
.savebar-bulk .clr:hover{color:#fff}
.savebar-bulk .sp{margin-left:auto;display:flex;gap:9px;flex-wrap:wrap;align-items:center;
  font-size:13px;color:#9fb0d0}

/* KPI tiles that double as filters. A <button> so it is keyboard-reachable and announced as
   actionable — a clickable <div> would be neither. */
.kpi-tile{text-align:left;font:inherit;cursor:pointer;width:100%;transition:.15s var(--ease)}
.kpi-tile:hover{border-color:var(--border-strong);transform:translateY(-2px);box-shadow:var(--shadow-md)}
.kpi-tile.on{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.kpi-tile:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}

/* Checkbox column */
.tbl th.ck,.tbl td.ck{width:44px;padding-right:0}
/* A header checkbox that carries its own "(Select All)" label. width:1% is the table idiom for
   shrink-to-fit: the column takes exactly the label's width and no more, so the body rows below it
   don't inherit a wide empty gutter between the checkbox and the first real column. */
.tbl th.ck:has(.selall){width:1%;white-space:nowrap;padding-right:var(--s3)}
.selall{display:inline-flex;align-items:center;gap:7px;cursor:pointer;white-space:nowrap}
.selall span{font-size:11px;font-weight:700;letter-spacing:.02em;text-transform:none;color:var(--text-2)}
.tbl tr.sel{background:var(--teal-wash)}
.tbl tbody tr.sel:hover{background:rgba(22,184,166,.16)}
.tbl tbody tr.row-muted{opacity:.6}

/* Application workflow: the small fact lines under a stage label, and the row's action cluster.
   Deliberately body-coloured rather than green/red — these are facts about the record (who is
   reviewing it, when a link went out, why it was turned down), not statuses to be read at a glance,
   and colouring them would make the column read as a traffic light. */
.appnote{font-size:11.5px;color:var(--text-2);margin-top:4px;line-height:1.35}
.rowacts{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:flex-end}

/* Checkbox that sits on its own line beside a label, inside a modal or a field. */
.cbline{display:flex;align-items:center;gap:9px;cursor:pointer;font-size:13.5px;margin-bottom:var(--s4)}

/* The trailing button row every confirmation modal ends with. */
.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:var(--s5)}

/* Required-field marker beside a label. */
.req{color:var(--rose)}

/* Read-only render of an email exactly as it will be sent. Scrolls rather than growing the modal,
   and neutralises the message's own margins so a template can't blow the layout out. */
.mailprev{max-height:340px;overflow-y:auto;border:1.5px solid var(--border);border-radius:var(--r-md);
  padding:14px 16px;background:var(--surface-2);font-size:13.5px;line-height:1.55}
.mailprev :is(p,ul,ol){margin:0 0 10px}
.mailprev :last-child{margin-bottom:0}
.mailprev img{max-width:100%;height:auto}

/* The "these will be skipped" list in the bulk confirmation. */
.skiplist{max-height:190px;overflow-y:auto;border:1.5px solid var(--border);border-radius:var(--r-md);padding:10px 12px}

/* Person cell (name over email) */
.pcell{display:flex;align-items:center;gap:10px;min-width:0}
.pcell .nm{font-weight:600;font-size:14px;line-height:1.25}
.pcell .em{font-size:12.5px;color:var(--text-3)}

/* Audit timeline */

/* A history is open-ended, so the page it sits on must not be. Wrapping a .tl in this caps it and
   moves the scrolling inside the card: the search box above it and the caveats below stay put
   instead of being pushed off the bottom by a record with two years of edits on it.
   scrollbar-gutter reserves the bar's width at all times, so the rows don't shift sideways the
   moment the list grows past the cap.

   The cap has to fit the SCREEN, not just be a number. A box taller than the viewport is one the
   reader can never see the end of, so the wheel appears dead: it is scrolling an inner list whose
   bottom is off-screen. 70vh keeps the whole box — and its scrollbar — visible, with 1400px as the
   ceiling on a very tall monitor.

   And no overscroll-behavior: scroll chaining is what everyone expects. Reaching the end of the
   list must carry on scrolling the page, or the pointer has to be moved off the content to get out
   of it, which is exactly the trap this is avoiding. */
.tl-scroll{max-height:min(1400px,70vh);overflow-y:auto;scrollbar-gutter:stable;
  padding-right:var(--s2);margin-bottom:var(--s5)}
/* The timeline's own bottom margin would scroll with it; the gap belongs to the container instead. */
.tl-scroll>.tl{margin-bottom:0}

.tl{position:relative;padding-left:26px;margin-bottom:var(--s5)}
.tl::before{content:"";position:absolute;left:8px;top:6px;bottom:6px;width:2px;background:var(--border)}
.tlrow{position:relative;padding:9px 0}
.tlrow::before{content:"";position:absolute;left:-22px;top:15px;width:11px;height:11px;border-radius:50%;
  background:var(--surface);border:2.5px solid var(--border-strong)}
.tlrow.sent::before{border-color:var(--navy-soft)}
.tlrow.open::before{border-color:var(--teal);background:var(--teal)}
.tlrow.click::before{border-color:var(--violet);background:var(--violet)}
.tlrow.fail::before{border-color:var(--rose);background:var(--rose)}
.tlrow .h{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.tlrow .h .t{font-weight:600;font-size:14px}
.tlrow .h .w{font-size:12px;color:var(--text-3);margin-left:auto;white-space:nowrap}
.tlrow .m{font-size:12.5px;color:var(--text-2);margin-top:3px;word-break:break-word}

/* Old → new pairs under a timeline row (contact audit). The label column is fixed so field names line
   up down the list and the eye can scan them; the values wrap freely, because a bio is a paragraph. */
.chg{display:flex;flex-direction:column;gap:3px;margin-top:6px}
.chg .r{display:flex;align-items:baseline;gap:var(--s2);flex-wrap:wrap;font-size:12.5px;line-height:1.5}
.chg .f{font-weight:600;color:var(--text-2);flex:0 0 160px;max-width:160px;word-break:break-word}
.chg .o{color:var(--text-3);text-decoration:line-through;word-break:break-word}
.chg .a{color:var(--text-3)}
.chg .n{color:var(--text);font-weight:500;word-break:break-word;flex:1;min-width:0}

/* Per-link click rollup */
.linkrow{display:flex;align-items:center;gap:var(--s3);padding:9px 0;border-bottom:1px solid var(--border)}
.linkrow:last-child{border-bottom:none}
.linkrow .lt{font-size:13.5px;font-weight:600;min-width:0;flex:1}
.linkrow .lu{font-size:11.5px;color:var(--text-3);word-break:break-all;font-weight:400;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.linkrow .bar{margin-top:0;width:120px;flex-shrink:0;max-width:120px}
.linkrow .bar i{display:block;height:100%;background:var(--teal);border-radius:inherit}
.linkrow .lc{font-size:13px;font-weight:700;min-width:56px;text-align:right;font-variant-numeric:tabular-nums}

/* Explanatory box inside a form (why a thing behaves the way it does) */
.callout{border:1px dashed var(--border-strong);border-radius:var(--r-md);padding:var(--s4);
  background:var(--surface-2);font-size:13px;color:var(--text-2);margin-top:var(--s4)}
.callout strong{color:var(--text)}

/* Checkbox + explanation rows in the send modal */
.switchrow{display:flex;align-items:flex-start;gap:11px;padding:9px 0}
.switchrow label{cursor:pointer}
.switchrow .t{display:block;font-size:14px;font-weight:600}
.switchrow .d{display:block;font-size:12.5px;color:var(--text-3);margin-top:2px}

.alert-tight{margin-top:var(--s4)}

/* ============================================================
   RUN PROGRESS — live bar for long-running staff actions
   (Kit/RunProgress.razor). Full-width sibling of .bar, which is
   the narrow inline variant used inside cards and rows.
   ============================================================ */
.runprog{margin-top:var(--s4)}
.runprog-top{display:flex;align-items:center;justify-content:space-between;gap:var(--s4)}
.runprog-what{display:flex;align-items:center;gap:11px;min-width:0}
.runprog-phase{font-size:15px;font-weight:600;letter-spacing:-.01em;margin-top:2px}
.runprog-pct{font-size:24px;font-weight:700;color:var(--teal);line-height:1;flex-shrink:0}
.runprog-pct span{font-size:14px;font-weight:600;margin-left:1px}

.runprog-spin{width:18px;height:18px;border-radius:50%;flex-shrink:0;
  border:2px solid var(--surface-3);border-top-color:var(--teal);
  animation:runprog-spin .8s linear infinite}
@keyframes runprog-spin{to{transform:rotate(360deg)}}

.runprog-track{height:9px;border-radius:5px;background:var(--surface-3);overflow:hidden;
  margin-top:var(--s3);position:relative}
.runprog-track i{display:block;height:100%;background:var(--teal);border-radius:5px;
  transition:width .3s var(--ease)}

/* Before the first tick there is no percentage to show, so the track sweeps instead of sitting empty. */
.runprog-track.is-waiting::after{content:"";position:absolute;inset:0;border-radius:5px;
  background:linear-gradient(90deg,transparent,var(--teal-wash),transparent);
  animation:runprog-sweep 1.2s ease-in-out infinite}
@keyframes runprog-sweep{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}

.runprog-foot{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);
  margin-top:8px;font-size:12px}
.runprog-foot .sub{font-size:12px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.runprog-note{font-size:12px;margin-top:6px}

@media (prefers-reduced-motion: reduce){
  .runprog-spin{animation-duration:2.4s}
  .runprog-track.is-waiting::after{animation:none}
  .runprog-track i{transition:none}
}

/* ── Field validation ─────────────────────────────────────────────────────────
   A form that refuses to save has to say which of its inputs it means. The rose
   ring marks the field; .fld-err carries the sentence directly under it. Shared,
   not scoped to one page — every required form wants this. */
.inp.err,
.err .dtp .dtp-field,
.err .ta .ta-field{border-color:var(--rose);box-shadow:0 0 0 3px var(--rose-wash)}
.fld-err{display:block;color:#b13a3a;font-size:12px;font-weight:600;margin-top:5px}

/* ── One-on-one meeting management (faculty 1:1 hub) ──────────────────────── */
.oo-form{display:grid;gap:var(--s3);grid-template-columns:1fr}
@media(min-width:680px){
  .oo-form{grid-template-columns:1fr 1fr}
  .oo-form .oo-wide{grid-column:1 / -1}
}

.oo-tiles{display:grid;gap:var(--s3);grid-template-columns:repeat(2,1fr);margin-top:var(--s4)}
@media(min-width:680px){.oo-tiles{grid-template-columns:repeat(4,1fr)}}

.oo-card-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.oo-card-head .oo-with{margin-left:auto;font-size:12px;color:var(--text-2)}
.oo-title{font-weight:600}
.oo-when{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:6px;
  font-size:13px;color:var(--text-2)}
.oo-when [data-localtime]{color:var(--text-3)}
.oo-actions{margin-top:12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* The audit line: quiet by design — it is provenance, not content. */
.oo-stamp{margin-top:8px;font-size:12px;color:var(--text-3)}

.oo-filters{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap;margin-bottom:var(--s3)}
.oo-filters .search{flex:1;min-width:220px}

/* ============================================================
   ACCOUNT LAYOUT — LEFT TAB RAIL + CONTENT PANE  (Kit/SideTabs)
   Used by /profile. A long single-column form of stacked cards reads as a wall; the rail turns it
   into four short pages (Basic details · Leadership · Sign-in & security · Notifications) and stays
   on screen while the pane scrolls, so "where am I" is always answered.
   ============================================================ */
.acct{display:grid;gap:var(--s5);align-items:start;grid-template-columns:1fr;margin-top:var(--s5)}
@media(min-width:1000px){.acct{grid-template-columns:264px minmax(0,1fr)}}

/* Sticky only where there is a column to be sticky in: below 1000px the rail is a horizontal pill
   strip at the top of the page, and pinning that would eat the viewport. The top offset clears the
   two-row fixed header (64px bar + sub-bar), a couple of px under it so no gap shows through. */
.acct-rail{display:flex;flex-direction:column;gap:var(--s4)}
@media(min-width:1000px){.acct-rail.acct-rail-sticky{position:sticky;top:132px}}

/* Identity block at the top of the rail — avatar, name, cohort, sync chip. */
.acct-me{display:flex;align-items:flex-start;gap:var(--s3);padding:var(--s4);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-sm)}
.acct-me .nm{font-weight:600;font-size:15px;line-height:1.25}
.acct-me .co{font-size:12.5px;color:var(--text-2)}
.acct-me .sy{margin-top:6px}

.acct-nav{display:flex;flex-direction:column;gap:4px}
.acct-nav button{display:flex;align-items:center;gap:11px;width:100%;text-align:left;padding:11px 14px;
  border-radius:var(--r-md);font-size:14.5px;font-weight:500;color:var(--text-2);
  transition:background .15s var(--ease),color .15s var(--ease)}
.acct-nav button .ic{display:grid;place-items:center;flex:0 0 auto;opacity:.8}
.acct-nav button:hover{background:var(--surface-2);color:var(--text)}
.acct-nav button.active{background:var(--navy);color:#fff;font-weight:600}
.acct-nav button.active .ic{opacity:1}
@media(max-width:999px){
  .acct-nav{flex-direction:row;gap:var(--s2);overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
  .acct-nav::-webkit-scrollbar{display:none}
  .acct-nav button{width:auto;border-radius:var(--r-pill);white-space:nowrap}
}

/* ---------- Grouped form card (Kit/FormSection + Kit/PaneFoot) ----------
   Sections inside ONE card, split by hairlines, instead of a card per heading. The card is rendered
   Padded="false" so each section owns its own padding and the rules can run edge to edge. */
.formsec{padding:var(--s5)}
.formsec + .formsec{border-top:1px solid var(--border)}
.formsec-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:var(--s4)}
.formsec-head h3{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--text-3)}
.formsec-head .gh{font-size:12.5px;color:var(--text-3)}
.formsec > .field:last-child{margin-bottom:0}

/* Card title row for panes whose card names itself (Leadership, Email, Password, Notifications). */
.cardhead{display:flex;align-items:center;gap:var(--s3);padding:var(--s5) var(--s5) 0}
.cardhead h2{font-size:17px;font-weight:600;letter-spacing:-.01em}
.cardhead .sp{margin-left:auto}
.cardhead + .formsec{padding-top:var(--s4)}

/* One save per tab, in a tinted footer with a line of context to its left. Explicit bottom radius:
   the card isn't clipped (Typeahead/DatePicker popups escape it), so the bar has to round itself. */
.panefoot{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;padding:var(--s4) var(--s5);
  border-top:1px solid var(--border);background:var(--surface-2);
  border-radius:0 0 var(--r-lg) var(--r-lg)}
.panefoot .fh{font-size:12.5px;color:var(--text-2)}
.panefoot .sp{margin-left:auto;display:flex;gap:9px;flex-wrap:wrap}

/* ---------- Form grids ----------
   Denser than .grid-2: short fields go four across on a wide pane, three or two as it narrows. The
   gap does the spacing, so .field's own bottom margin is cancelled inside a grid. */
.fgrid{display:grid;gap:var(--s4)}
.fgrid .field{margin-bottom:0}
.fgrid + .fgrid,.fgrid + .field{margin-top:var(--s4)}
@media(min-width:700px){
  .fgrid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fgrid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
  .fgrid-4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(min-width:1200px){.fgrid-4{grid-template-columns:repeat(4,minmax(0,1fr))}}

/* Identity row: the photo gets a column of its own, the naming fields sit beside it. */
.idrow{display:grid;gap:var(--s5);grid-template-columns:1fr}
@media(min-width:760px){.idrow{grid-template-columns:196px minmax(0,1fr)}}

.checkrow{display:flex;align-items:flex-start;gap:10px;font-size:14px;cursor:pointer}
.checkrow input{width:17px;height:17px;margin-top:2px;flex:0 0 auto;accent-color:var(--teal)}
.checkrow .cs{display:block;margin-top:1px;font-size:12.5px;color:var(--text-3)}

/* ---------- AvatarUpload, large variant (profile) ----------
   The 64px thumbnail reads as a field decoration; at 148px the photo reads as the thing the section
   is about, which is what it is. Actions stack under it so the column stays narrow. */
.avatarupload-lg{flex-direction:column;align-items:center;gap:var(--s3);text-align:center}
.avatarupload-lg .avatarupload-body{align-items:center;width:100%;gap:var(--s3)}
.avatarupload-lg .avatarupload-actions{flex-direction:column;width:100%;gap:8px}
.avatarupload-lg .avatarupload-actions > *{width:100%}
.avatarupload-lg .avatarupload-hint{font-size:11.5px;line-height:1.45}
.avatarupload-pic{width:148px;height:148px;border-radius:50%;overflow:hidden;flex:0 0 auto;
  background:linear-gradient(135deg,var(--navy),var(--teal));display:grid;place-items:center;
  color:#fff;font-size:46px;font-weight:700;letter-spacing:-.02em;
  box-shadow:0 0 0 6px var(--surface),0 0 0 7px var(--border)}
.avatarupload-pic img{width:100%;height:100%;object-fit:cover;display:block}
/* Inline confirmation that the crop actually landed on the server — a toast alone left members
   unsure, and clicking the page's Save button "to be safe" was the tell. */
.avatarupload-saved{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;
  color:var(--teal-deep)}

/* Quiet helper line under a single field ("At least 8 characters."). Distinct from .sub, which is a
   paragraph voice — this one belongs to the input above it. */
.field .hint{margin-top:5px;font-size:12px;color:var(--text-3)}

/* ---------- Staff Help Center (/staff/help — DOCUMENTATION_PLAN.md, Option C "manual") ----------
   Reuses the .acct grid + SideTabs rail from Settings/Profile; these classes are only the reading
   surface: search sizing, list rows, the article template, and the book-style prev/next footer. */
.help-search{margin-bottom:var(--s4)}
.help-search input{font-size:15.5px;padding-top:13px;padding-bottom:13px}
.help-pane{padding:var(--s2) 0}

.help-reshead{padding:var(--s3) var(--s5) 2px;font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text-3)}
.help-qhit{display:block;width:100%;text-align:left;padding:var(--s3) var(--s5)}
.help-qhit:hover{background:var(--surface-2)}
.help-qhit .q{display:block;font-weight:600;font-size:15px}
.help-qhit .a{display:block;color:var(--text-2);font-size:14px;margin-top:2px;max-width:70ch}
.help-qhit .more{display:inline-block;margin-top:4px;font-size:13px;font-weight:600;color:var(--teal-deep)}
.help-ahit{display:flex;align-items:center;gap:var(--s3);width:100%;text-align:left;padding:var(--s3) var(--s5)}
.help-ahit:hover{background:var(--surface-2)}
.help-ahit .t{font-weight:500;flex:1}

.help-row{display:block;width:100%;text-align:left;padding:var(--s4) var(--s5);
  border-bottom:1px solid var(--border)}
.help-row:last-child{border-bottom:none}
.help-row:hover{background:var(--surface-2)}
.help-row .t{display:block;font-weight:600;font-size:15px}
.help-row .s{display:block;color:var(--text-2);font-size:13.5px;margin-top:2px}

.help-backbar{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;
  padding:var(--s4) var(--s5) 0}
.help-secnav{display:flex;gap:6px;flex-wrap:wrap}
.help-secnav button{padding:5px 12px;border-radius:var(--r-pill);background:var(--surface-2);
  font-size:12.5px;font-weight:500;color:var(--text-2)}
.help-secnav button:hover{background:var(--teal-wash);color:var(--teal-press)}

.help-art{padding:var(--s5) var(--s6) var(--s4)}
.help-crumb{font-size:13px;color:var(--text-3);margin-bottom:var(--s3)}
.help-art h2{font-size:24px;font-weight:600;letter-spacing:-.02em;margin:0 0 var(--s3)}
.help-summary{background:var(--teal-wash);border-left:3px solid var(--teal);
  border-radius:0 var(--r-md) var(--r-md) 0;padding:var(--s3) var(--s4);font-size:15px}

.help-sec{margin-top:var(--s5);border-radius:var(--r-sm)}
/* jcp.scrollToId adds .flash to the jumped-to section (same helper the rest of the app uses). */
.help-sec.flash{box-shadow:0 0 0 3px var(--teal-wash);background:var(--teal-wash)}
.help-sec .snum{font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--teal-deep);margin-bottom:var(--s2)}
.help-sec p{color:var(--text-2);margin:0 0 var(--s2);max-width:72ch}
.help-sec p b{color:var(--text);font-weight:600}

.help-act{display:flex;gap:var(--s4);padding:var(--s3) 0;border-bottom:1px solid var(--border)}
.help-act:last-child{border-bottom:none}
.help-act .do{flex:0 0 230px;font-weight:600;font-size:14px}
.help-act .fx{color:var(--text-2);font-size:14px}
@media(max-width:700px){.help-act{flex-direction:column;gap:4px}.help-act .do{flex:none}}

details.help-qa{border-bottom:1px solid var(--border)}
details.help-qa:last-child{border-bottom:none}
details.help-qa summary{list-style:none;cursor:pointer;padding:var(--s3) 0;font-weight:600;
  font-size:14.5px;display:flex;gap:10px;align-items:baseline}
details.help-qa summary::-webkit-details-marker{display:none}
details.help-qa summary .tw{color:var(--teal);font-weight:700;transition:transform .15s var(--ease)}
details.help-qa[open] summary .tw{transform:rotate(90deg)}
details.help-qa .ans{color:var(--text-2);font-size:14px;padding:0 0 var(--s3) 22px;max-width:70ch}

.help-rel{display:flex;flex-wrap:wrap;gap:var(--s2)}
.help-relchip{padding:7px 14px;border-radius:var(--r-pill);border:1px solid var(--border);
  background:var(--surface);font-size:13.5px;font-weight:500;color:var(--text-2)}
.help-relchip:hover{border-color:var(--teal);color:var(--teal-press);background:var(--teal-wash)}

.help-pn{display:flex;justify-content:space-between;gap:var(--s3);
  padding:var(--s4) var(--s5) var(--s5)}
.help-pn .pn-btn{max-width:46%;text-align:left;padding:var(--s3) var(--s4);
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface)}
.help-pn .pn-btn:hover{border-color:var(--teal)}
.help-pn .pn-btn .lbl{display:block;font-size:12px;font-weight:600;color:var(--text-3)}
.help-pn .pn-btn b{display:block;font-size:14px;color:var(--text)}
.help-pn .pn-btn.next{text-align:right;margin-left:auto}

/* ============================================================
   ASKS & OFFERS BOARD  (ASKS_AND_OFFERS_PROPOSAL.md)
   Cards only — members never see a table (DESIGN.md §1). Ported from
   "Mock - Asks and Offers.html". One primary action per screen: the teal Post button.
   ============================================================ */

/* Neutral chip. The kit shipped teal|navy|amber|violet|rose, all of which carry meaning; a board card
   stacks a kind chip next to a category chip, and the category is the one that should say nothing. */
.chip-grey{background:var(--surface-2);color:var(--text-2)}

.boardhead{display:flex;gap:var(--s4);align-items:flex-end;flex-wrap:wrap;margin-bottom:var(--s4)}
.boardhead-title{flex:1 1 260px}
.boardhead-actions{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap}
.boardhead-actions .search{min-width:260px}
.board-filters{margin-bottom:var(--s4)}

.board-feed{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s4)}
.board-post{padding:var(--s4) var(--s5)}
.board-post-inner{display:flex;gap:var(--s4);align-items:flex-start}
.board-post-body{flex:1;min-width:0}
.board-post-chips{display:flex;gap:var(--s2);flex-wrap:wrap;margin-bottom:var(--s2)}
.board-post-title{font-size:16.5px;font-weight:600;line-height:1.35;margin-bottom:6px}
.board-post-title a:hover{color:var(--teal-press)}
/* Three lines then an ellipsis: the headline is what people scan, the detail is context. */
.board-post-excerpt{color:var(--text-2);font-size:14px;line-height:1.55;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.board-post-foot{display:flex;gap:var(--s3);flex-wrap:wrap;align-items:center;
  margin-top:var(--s3);font-size:12.5px;color:var(--text-3)}
.board-post-who{color:var(--text-2);font-weight:500}
.board-edited{font-style:italic}
.board-post-actions{display:flex;gap:var(--s2);flex-wrap:wrap;align-items:center;margin-top:var(--s3)}

/* Reaction pill. "on" is a real state — the member has tapped it — so it earns the teal wash. */
.board-react{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border-radius:var(--r-pill);
  border:1px solid var(--border);background:var(--surface);font-size:13px;font-weight:500;color:var(--text-2);
  transition:border-color .12s var(--ease),background .12s var(--ease),color .12s var(--ease)}
.board-react:hover{border-color:var(--teal);color:var(--teal-press);background:var(--teal-wash)}
.board-react.on{border-color:var(--teal);background:var(--teal-wash);color:var(--teal-deep)}
.board-react.is-static{cursor:default;border-style:dashed}
.board-react.is-static:hover{border-color:var(--border);color:var(--text-2);background:var(--surface)}
.board-n{font-variant-numeric:tabular-nums;font-weight:600}

.board-back{display:inline-flex;align-items:center;gap:6px;color:var(--text-2);font-size:13.5px;
  font-weight:500;margin-bottom:var(--s4)}
.board-back:hover{color:var(--teal-press)}
.board-foot{margin-top:var(--s5);font-size:13px}
.board-foot a{color:var(--teal-deep);font-weight:500;margin-left:6px}

/* ---- composer: form and live preview side by side, stacking on narrow screens ---- */
.board-compose{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:var(--s5);
  align-items:start}
.board-compose-pane{display:flex;flex-direction:column;gap:var(--s4)}
.board-compose-aside{display:flex;flex-direction:column;gap:var(--s4);position:sticky;top:var(--s4)}
.board-lab{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text-3);margin-bottom:var(--s2)}
.board-tips ul{margin:0;padding-left:18px;color:var(--text-2);font-size:13.5px;line-height:1.6}
.board-tips li+li{margin-top:6px}

.board-seg{display:inline-flex;padding:4px;background:var(--surface-2);border-radius:var(--r-pill);gap:4px}
.board-seg button{padding:8px 16px;border-radius:var(--r-pill);font-size:13.5px;font-weight:500;
  color:var(--text-2)}
.board-seg button.on{background:var(--surface);color:var(--navy);font-weight:600;box-shadow:var(--shadow-sm)}

.board-radiorow{display:flex;gap:var(--s3);flex-wrap:wrap}
.board-radio{display:inline-flex;align-items:center;gap:8px;padding:9px 15px;border-radius:var(--r-pill);
  border:1px solid var(--border);font-size:13.5px;color:var(--text-2);cursor:pointer}
.board-radio.on{border-color:var(--teal);background:var(--teal-wash);color:var(--teal-deep);font-weight:500}

.board-callout{display:flex;gap:var(--s3);padding:var(--s4);border-radius:var(--r-md);
  background:var(--surface-2);color:var(--text-2);font-size:13.5px;line-height:1.55}
.board-savebar{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap}
/* Generic, not board-specific: `.field .hint` already existed with these values, and the board's
   composer uses `.fld`. Promoted to a bare rule rather than duplicated under a board selector. */
.hint{margin-top:5px;font-size:12px;color:var(--text-3)}
/* Not --rose: a character count that is merely short is not a failure (DESIGN.md §1). */
.hint-warn{color:var(--violet-deep)}

/* ---- detail + thread ---- */
.board-detail{display:flex;flex-direction:column;gap:var(--s4)}
.board-detail-head{display:flex;gap:var(--s4);align-items:flex-start}
.board-detail-meta{color:var(--text-3);font-size:12.5px;display:flex;gap:5px;flex-wrap:wrap}
.board-detail-body{color:var(--text-2);font-size:15px;line-height:1.65;white-space:pre-wrap}
.board-solvebar{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;
  padding-top:var(--s4);border-top:1px solid var(--border)}
.board-spacer{flex:1}

.board-replies{display:flex;flex-direction:column;gap:var(--s3);margin-top:var(--s4)}
.board-reply{display:flex;gap:var(--s3);align-items:flex-start}
/* The credited reply is the one piece of recognition this feature gives out. A left rule, not a badge
   colour on the whole card — recognition, not ranking (DESIGN.md §1). */
.board-reply.credited{border-left:3px solid var(--teal)}
.board-reply-body{flex:1;min-width:0}
.board-reply-head{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;margin-bottom:6px}
.board-reply-meta{color:var(--text-3);font-size:12.5px}
.board-credit{margin-left:auto}
.board-reply-text{color:var(--text-2);font-size:14.5px;line-height:1.6;white-space:pre-wrap}
.board-reply-hidden{color:var(--text-3);font-size:13.5px;font-style:italic}
.board-reply-actions{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap;margin-top:var(--s3)}
.board-composer{display:flex;flex-direction:column;gap:var(--s3)}

/* ---- My posts: a management list, not the feed. One row per post, one action that fits its state. */
.board-mine-row{display:flex;gap:var(--s4);align-items:flex-start;padding:var(--s4) var(--s5);
  border-bottom:1px solid var(--border)}
.board-mine-list > .board-mine-row:last-child{border-bottom:0}
.board-mine-row.scheduled{background:var(--amber-wash)}
.board-mine-row.closed{opacity:.72}
.board-mine-chip{flex:0 0 auto;padding-top:2px}
.board-mine-body{flex:1;min-width:0}
.board-mine-title{display:block;font-weight:600;font-size:15px;line-height:1.4}
.board-mine-title:hover{color:var(--teal-press)}
.board-mine-meta{display:flex;gap:var(--s3);flex-wrap:wrap;align-items:center;
  margin-top:5px;font-size:12.5px;color:var(--text-3)}
/* The reply count is the emotional content of the row, so it is the only coloured thing on it. */
.board-mine-answered{color:var(--teal-press);font-weight:600}
.board-mine-quiet{color:var(--amber-deep);font-weight:600}
.board-mine-credit{color:var(--violet-deep);font-weight:600}
.board-mine-acts{flex:0 0 auto;display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;
  justify-content:flex-end}
.board-mine-acts .danger{color:var(--rose)}
.board-mine-nudge{padding:0 var(--s5) var(--s4);margin-top:calc(var(--s3) * -1);
  font-size:12.5px;color:var(--text-2);border-bottom:1px solid var(--border)}
.board-mine-hidden{color:var(--violet-deep)}
.board-mine-hidden strong{display:block}

/* ---- home teaser: the navy hero, asking the member to give rather than to consume ---- */
.board-teaser .board-teaser-list{position:relative;display:flex;flex-direction:column;gap:2px;
  /* .hero p already carries a bottom margin; only the bottom gap is ours to add. */
  margin:0 0 var(--s4);padding:var(--s2) 0;border-top:1px solid rgba(255,255,255,.14);
  border-bottom:1px solid rgba(255,255,255,.14)}
.board-teaser-row{display:flex;gap:var(--s3);align-items:center;padding:9px var(--s2);
  border-radius:var(--r-sm);transition:background .12s var(--ease)}
.board-teaser-row:hover{background:rgba(255,255,255,.08)}
.board-teaser-q{flex:1;min-width:0;font-size:14px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.board-teaser-who{flex:0 0 auto;font-size:12.5px;opacity:.72}
/* A chip readable on the navy hero — the kit's washes assume a light surface. */
.chip-onnavy{background:rgba(255,255,255,.16);color:#fff}

/* ---- staff moderation table ---- */
.board-mod{margin-top:var(--s4)}

@media (max-width:900px){
  .board-compose{grid-template-columns:1fr}
  .board-compose-aside{position:static}
  .boardhead-actions{width:100%}
  .boardhead-actions .search{flex:1;min-width:0}
}

/* Digest ordering rules (Staff → Messaging → Digest). A ranked list, not a sort dropdown: each rule
   contributes one tie-break in the order staff arrange them. */
.digest-rule{display:flex;align-items:center;gap:var(--s2);padding:10px var(--s3);
  border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface)}
.digest-rule.on{border-color:var(--teal);background:var(--teal-wash)}
.digest-rule .linkbtn{font-size:15px;line-height:1;padding:2px 6px;color:var(--text-2)}

/* ============================================================
   APPEARANCE (Staff → /staff/appearance)
   The one page in the portal that must NOT inherit the live theme in its previews — each preset card
   shows its own palette, so every colour inside a card comes from that card's inline custom properties
   rather than from :root. The chrome around them is ordinary kit.
   ============================================================ */
.apx-themes{display:grid;gap:var(--s4);grid-template-columns:1fr}
@media(min-width:760px){.apx-themes{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1180px){.apx-themes{grid-template-columns:repeat(3,1fr)}}

.apx-card{display:flex;flex-direction:column;overflow:hidden;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-md);transition:box-shadow .16s var(--ease),border-color .16s var(--ease)}
.apx-card:hover{box-shadow:var(--shadow-md)}
.apx-card.active{border-color:var(--teal);box-shadow:0 0 0 2px var(--teal-wash)}

/* The preview strip. Its colours are the PRESET's, injected as inline vars by the page — never :root. */
.apx-prev{padding:var(--s5) var(--s4);text-align:center;border-bottom:1px solid var(--apx-border);
  background:var(--apx-bg)}
.apx-prev-word{font-family:var(--apx-font);font-size:21px;font-weight:600;letter-spacing:-.02em;
  color:var(--apx-text);line-height:1.2}
.apx-prev-swatches{display:flex;justify-content:center;gap:9px;margin-top:var(--s4)}
.apx-prev-dot{width:22px;height:22px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.10)}

.apx-body{padding:var(--s4);display:flex;flex-direction:column;gap:6px;flex:1}
.apx-name{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  font-size:15.5px;font-weight:700;letter-spacing:-.01em}
.apx-blurb{font-size:13px;color:var(--text-2);line-height:1.5;flex:1}
.apx-font{font-size:12px;color:var(--text-3)}
.apx-act{margin-top:var(--s3)}

/* ---- fine-tune grid ---- */
.apx-tune{display:grid;gap:var(--s5) var(--s4);grid-template-columns:1fr;margin-top:var(--s4)}
@media(min-width:640px){.apx-tune{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1100px){.apx-tune{grid-template-columns:repeat(4,1fr)}}

.apx-swatch-field{min-width:0}
.apx-swatch-label{font-size:13px;font-weight:700;margin-bottom:6px}
.apx-swatch-row{display:flex;gap:var(--s3);align-items:flex-start}
/* A native colour input, restyled to the chip the mock shows. Native is deliberate: it brings the OS
   eyedropper and colour picker, which no hand-built picker can match. */
.apx-swatch{flex:0 0 auto;width:46px;height:38px;padding:3px;cursor:pointer;background:var(--surface);
  border:1.5px solid var(--border-strong);border-radius:var(--r-sm)}
.apx-swatch::-webkit-color-swatch-wrapper{padding:0}
.apx-swatch::-webkit-color-swatch{border:none;border-radius:calc(var(--r-sm) - 3px)}
.apx-swatch::-moz-color-swatch{border:none;border-radius:calc(var(--r-sm) - 3px)}
.apx-swatch:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-wash)}
.apx-swatch-help{flex:1;min-width:0;font-size:12.5px;color:var(--text-2);line-height:1.45}
.apx-swatch-hex{display:block;margin-top:3px;font-size:11.5px;color:var(--text-3);
  font-variant-numeric:tabular-nums;text-transform:uppercase}

/* Contrast readout. Shown only where the ratio actually decides legibility. */
.apx-ratio{display:inline-flex;align-items:center;gap:5px;margin-top:5px;padding:2px 8px;
  border-radius:var(--r-pill);font-size:11px;font-weight:700;letter-spacing:.02em}
.apx-ratio.pass{background:var(--teal-wash);color:var(--teal-deep)}
.apx-ratio.warn{background:var(--amber-wash);color:var(--amber-deep)}
.apx-ratio.fail{background:var(--rose-wash);color:#d84a4a}

/* ---- roundness + motion row ---- */
.apx-geo{display:grid;gap:var(--s5);grid-template-columns:1fr;margin-top:var(--s5);
  padding-top:var(--s5);border-top:1px solid var(--border)}
@media(min-width:820px){.apx-geo{grid-template-columns:1fr 1fr;align-items:start}}
.apx-range{width:100%;accent-color:var(--teal);margin-top:var(--s2)}
.apx-range-scale{display:flex;justify-content:space-between;font-size:11.5px;color:var(--text-3);margin-top:2px}
.apx-corner{display:flex;gap:var(--s3);align-items:center;margin-top:var(--s3)}
.apx-corner-box{width:52px;height:38px;background:var(--surface-2);border:1.5px solid var(--border-strong)}
.apx-check{display:flex;gap:var(--s3);align-items:flex-start;cursor:pointer}
.apx-check input{margin-top:3px;width:17px;height:17px;accent-color:var(--teal);flex:0 0 auto}
.apx-check-text{font-size:14px;font-weight:600}
.apx-check-help{display:block;margin-top:3px;font-size:12.5px;font-weight:400;color:var(--text-2);line-height:1.5}

/* Sticky action bar — the fine-tune grid is tall enough that Save would otherwise scroll away. */
.apx-save{position:sticky;bottom:0;z-index:5;display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap;
  margin-top:var(--s5);padding:var(--s4) 0;background:var(--bg);border-top:1px solid var(--border)}
.apx-save-note{font-size:12.5px;color:var(--text-2);margin-right:auto}
.digest-rule .linkbtn:disabled{opacity:.3;cursor:default;text-decoration:none}
.digest-rank{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;
  border-radius:var(--r-pill);background:var(--teal);color:#fff;font-size:12px;font-weight:600;
  font-variant-numeric:tabular-nums}

/* ============================================================
   ANALYTICS (Staff → Analytics, DESIGN.md §5: KpiTile, TrendChart, BarList, FunnelChart)
   ============================================================ */
.an-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s4);flex-wrap:wrap}
/* overflow-x:auto alone also makes the vertical axis "auto", and the tabs deliberately hang 1px over
   the strip's border (margin-bottom:-1px) — that 1px was enough to summon a vertical scrollbar. */
.an-nav{display:flex;gap:var(--s1);border-bottom:1px solid var(--border);margin:var(--s4) 0;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}
.an-nav a{display:inline-flex;align-items:center;gap:6px;padding:10px 14px;font-size:14px;font-weight:600;color:var(--text-2);
  border-radius:var(--r-sm) var(--r-sm) 0 0;border-bottom:2px solid transparent;white-space:nowrap;margin-bottom:-1px}
.an-nav a:hover{color:var(--text);background:var(--surface-2)}
.an-nav a.active{color:var(--text);background:var(--surface-2);border-bottom-color:var(--teal)}
.an-range{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;margin:0 0 var(--s4)}
.an-range .an-presets{display:flex;gap:6px;flex-wrap:wrap}
.an-range .an-preset{padding:6px 12px;border-radius:var(--r-pill);border:1px solid var(--border-strong);font-size:13px;font-weight:600;color:var(--text-2);background:var(--surface)}
.an-range .an-preset:hover{background:var(--surface-2);color:var(--text)}
.an-range .an-preset.active{background:var(--navy);border-color:var(--navy);color:#fff}
.an-range .an-custom{display:flex;align-items:center;gap:var(--s2);margin-left:auto;flex-wrap:wrap;font-size:12.5px;color:var(--text-2)}
.an-range .an-custom .dp{min-width:150px}
.an-range select{border:1.5px solid var(--border-strong);border-radius:var(--r-sm);padding:6px 10px;font-size:13px;background:var(--surface);color:var(--text)}

/* Generic KPI row, for any page that leads with a few headline numbers. .an-kpis below is the
   analytics hub's own 4/5/8-column variant; this one just flows as many tiles as fit, so a report
   with three summary figures doesn't need a bespoke grid. */
.tilerow{display:grid;gap:var(--s3);grid-template-columns:1fr;margin-top:var(--s4)}
@media(min-width:680px){.tilerow{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}}

/* A wrapping row of chips — a value list, a filter set, a tag cloud. */
.chiprow{display:flex;flex-wrap:wrap;gap:var(--s2)}

.an-kpis{display:grid;gap:var(--s3);grid-template-columns:repeat(2,1fr);margin-top:var(--s4)}
@media(min-width:680px){.an-kpis{grid-template-columns:repeat(4,1fr)}}
@media(min-width:1100px){.an-kpis.an-kpis-8{grid-template-columns:repeat(8,1fr)}.an-kpis.an-kpis-5{grid-template-columns:repeat(5,1fr)}}
.kpi{padding:var(--s4) var(--s4) var(--s3);border-bottom:3px solid var(--teal)}
.kpi .kpi-l{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3)}
.kpi .kpi-v{font-size:28px;font-weight:300;letter-spacing:-.02em;line-height:1.1;margin-top:6px}
.kpi .kpi-d{font-size:12px;font-weight:600;margin-top:6px;color:var(--text-3);display:flex;gap:4px;align-items:center}
.kpi .kpi-d.up{color:var(--teal-deep)}
.kpi .kpi-d.down{color:#d84a4a}
.kpi .kpi-d .kpi-vs{font-weight:500;color:var(--text-3)}
.kpi.kpi-live{border-bottom-color:var(--violet)}
.kpi.kpi-live .kpi-l::before{content:"●";color:var(--teal);margin-right:6px;font-size:9px;vertical-align:middle}

/* minmax(0,1fr), not 1fr: a bare 1fr track can't shrink below its content, so one long page path
   would squeeze the neighbouring cards to a word a line. Four-up is deliberately not offered — the
   lists in these cards carry paths and labels that need the width. */
.an-grid{display:grid;gap:var(--s4);grid-template-columns:minmax(0,1fr);margin-top:var(--s4)}
@media(min-width:900px){.an-grid-2,.an-grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}.an-grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
.an-grid>*{min-width:0}
.an-panel{display:flex;flex-direction:column;min-height:100%}
.an-panel-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s3)}
.an-panel-head h2{font-size:18px;font-weight:600;letter-spacing:-.01em}
.an-panel-head h3{font-size:16px;font-weight:600}
.an-panel-head>div:first-child{min-width:0}
.an-panel-head .sub{font-size:13px;margin-top:2px}
.an-panel-head .link{font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--text-2);white-space:nowrap}
.an-panel-head .link:hover{color:var(--teal-deep)}
.an-seg{display:flex;gap:2px;flex-wrap:wrap}
.an-seg button{padding:7px 12px;border-radius:var(--r-sm);font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-2)}
.an-seg button:hover{background:var(--surface-2);color:var(--text)}
.an-seg button.active{background:var(--navy);color:#fff}

/* TrendChart */
.trend{position:relative;width:100%}
.trend svg{display:block;width:100%;height:auto;overflow:visible}
.trend .tr-grid{stroke:var(--border);stroke-width:1}
.trend .tr-base{stroke:var(--border-strong);stroke-width:1}
.trend .tr-line{fill:none;stroke:var(--teal-deep);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.trend .tr-area{fill:var(--teal);opacity:.12}
.trend .tr-prev{fill:none;stroke:var(--text-3);stroke-width:1.5;stroke-dasharray:3 4;opacity:.8}
.trend .tr-dot{fill:var(--teal-deep);stroke:var(--surface);stroke-width:2}
.trend .tr-x{font-size:11px;fill:var(--text-3)}
.trend .tr-y{font-size:10.5px;fill:var(--text-3)}
.trend .tr-hit{fill:transparent}
.trend .tr-hit:hover + .tr-tip,.trend .tr-hit:focus + .tr-tip{opacity:1}
.trend .tr-tip{opacity:0;pointer-events:none;transition:opacity .12s}
.trend .tr-tip rect{fill:var(--navy);rx:6}
.trend .tr-tip text{fill:#fff;font-size:11px;font-weight:600}
.trend-legend{display:flex;gap:var(--s4);font-size:12px;color:var(--text-2);margin-top:var(--s2)}
.trend-legend span::before{content:"";display:inline-block;width:14px;height:0;border-top:2px solid var(--teal-deep);margin-right:6px;vertical-align:middle}
.trend-legend span.prev::before{border-top:2px dashed var(--text-3)}

/* BarList */
.barlist{display:flex;flex-direction:column;gap:6px}
.barlist .bl-row{position:relative;display:block;padding:8px 10px;border-radius:var(--r-sm);overflow:hidden;color:inherit;min-width:0}
.barlist .bl-row a{color:inherit}
.barlist .bl-fill{position:absolute;inset:0;width:var(--w,0%);background:var(--teal-wash);border-radius:var(--r-sm);transition:width .3s var(--ease)}
.barlist .bl-row.violet .bl-fill{background:var(--violet-wash)}
.barlist .bl-row.amber .bl-fill{background:var(--amber-wash)}
.barlist .bl-main{position:relative;display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3)}
.barlist .bl-label{font-size:13.5px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.barlist .bl-value{font-size:13.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.barlist .bl-sub{position:relative;font-size:11.5px;color:var(--text-3);margin-top:1px}
.barlist .bl-row.bl-link:hover{outline:1.5px solid var(--border-strong)}
.barlist-empty{padding:var(--s5);text-align:center;color:var(--text-3);font-size:13px;border:1px dashed var(--border-strong);border-radius:var(--r-md)}

/* FunnelChart */
.funnel{display:flex;flex-direction:column;gap:6px}
.funnel .fn-step{position:relative;padding:10px 12px;border-radius:var(--r-sm);overflow:hidden;border-left:3px solid var(--border-strong)}
.funnel .fn-fill{position:absolute;inset:0;width:var(--w,0%);background:var(--surface-3);border-radius:var(--r-sm)}
.funnel .fn-main{position:relative;display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3)}
.funnel .fn-label{font-size:14px;font-weight:600}
.funnel .fn-nums{display:flex;gap:8px;align-items:baseline;white-space:nowrap}
.funnel .fn-n{font-weight:700;font-variant-numeric:tabular-nums}
.funnel .fn-pct{font-size:12.5px;color:var(--text-2)}
.funnel .fn-sub{position:relative;font-size:11.5px;color:var(--text-3);margin-top:2px}
.funnel .fn-sub.lost{color:#b13a3a}
.funnel-end{font-size:14px;color:var(--text-2);margin-top:var(--s3)}

/* tables & odds and ends */
.an-tbl .path{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px}
.an-tbl td.num,.an-tbl th.num{text-align:right;font-variant-numeric:tabular-nums}
.an-tbl .muted{color:var(--text-3)}
.an-status{display:inline-flex;align-items:center;gap:6px;font-size:13px}
.an-status::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--teal)}
.an-status.paused::before{background:var(--amber)}
.an-status.bad::before{background:var(--rose)}
.an-feed{display:flex;flex-direction:column}
.an-feed .fd-row{display:grid;grid-template-columns:70px auto 1fr auto;gap:var(--s3);align-items:center;padding:9px 0;border-bottom:1px solid var(--border);font-size:13.5px}
.an-feed .fd-when{font-size:12px;color:var(--text-3);white-space:nowrap}
.an-feed .fd-what{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.an-feed .fd-what b{font-weight:600}
.an-feed .fd-who{font-size:12px;color:var(--text-2);white-space:nowrap}
.an-hours{display:flex;align-items:flex-end;gap:2px;height:120px;margin-top:var(--s3)}
.an-hours .hr{flex:1;background:var(--teal-wash);border-top:2px solid var(--teal-deep);border-radius:3px 3px 0 0;min-height:2px;position:relative}
.an-hours .hr[data-n]:hover::after{content:attr(data-n);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--navy);color:#fff;font-size:11px;padding:2px 6px;border-radius:6px;white-space:nowrap;margin-bottom:4px}
.an-hours-x{display:flex;justify-content:space-between;font-size:11px;color:var(--text-3);margin-top:4px}
.an-health dt{font-size:13.5px;color:var(--text-2)}
.an-health dd{font-size:13.5px;font-weight:600;text-align:right}
.an-health{display:grid;grid-template-columns:1fr auto;gap:10px var(--s4);margin:0}
.an-health dt,.an-health dd{padding:8px 0;border-bottom:1px solid var(--border);margin:0}
.an-note{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;font-size:13.5px;color:var(--text-2);display:flex;gap:10px;align-items:flex-start}
.an-note b{color:var(--text)}
.an-goal-form{display:grid;gap:var(--s3);grid-template-columns:1fr}
@media(min-width:800px){.an-goal-form{grid-template-columns:1fr 1fr 1fr}.an-goal-form .span2{grid-column:span 2}.an-goal-form .span3{grid-column:span 3}}
.an-member-row{cursor:pointer}
.an-session{border:1px solid var(--border);border-radius:var(--r-md);padding:12px 14px;margin-bottom:var(--s3)}
.an-session .ss-head{display:flex;justify-content:space-between;gap:var(--s3);flex-wrap:wrap;font-size:13px}
.an-session .ss-meta{color:var(--text-3);font-size:12px}
.an-session .ss-timeline{margin-top:8px;padding-left:14px;border-left:2px solid var(--border);display:flex;flex-direction:column;gap:4px;font-size:12.5px}
.an-session .ss-timeline .t{color:var(--text-3);margin-right:6px;font-variant-numeric:tabular-nums}

/* ---------- Session replay viewer (Analytics → Replays) ---------- */
.replay-layout{display:grid;gap:var(--s4);grid-template-columns:minmax(0,1fr);margin-top:var(--s4);align-items:start}
@media(min-width:1100px){.replay-layout{grid-template-columns:minmax(0,1fr) 340px}}
.replay-stage{overflow:hidden}
.replay-player{position:relative;min-height:320px;background:var(--surface-3);display:flex;align-items:center;justify-content:center}
.replay-player .replay-loading{color:var(--text-3);font-size:13.5px;padding:var(--s6)}
/* rrweb-player sizes itself in px from the width we hand it; keep it from overflowing the card. */
.replay-player .rr-player{max-width:100%;box-shadow:none!important;border-radius:0!important;background:var(--surface-2)}
.replay-player .rr-player__frame{background:var(--surface)}
/* The controller, restyled onto the navy bar. Every rule is scoped under .replay-player so it cannot
   leak into the Kit, and specific enough to beat the player's own Svelte-scoped selectors. */
.replay-player .rr-controller{background:var(--navy)!important;color:var(--text-on-navy)!important;font-family:var(--font-body)!important;height:84px!important}
.replay-player .rr-timeline{width:92%!important}
.replay-player .rr-timeline__time{color:var(--text-on-navy)!important;font-variant-numeric:tabular-nums;font-size:12.5px;width:64px!important;opacity:.9}
.replay-player .rr-progress{background:rgba(255,255,255,.18)!important;border-top-color:transparent!important;border-bottom-color:transparent!important}
.replay-player .rr-progress__step{background:var(--teal)!important}
.replay-player .rr-progress__handler{background:#fff!important;box-shadow:0 0 0 3px var(--teal)}
.replay-player .rr-controller__btns{gap:6px;color:var(--text-on-navy)!important}
.replay-player .rr-controller__btns button{color:var(--text-on-navy)!important;font-weight:600;font-family:var(--font-body)!important}
.replay-player .rr-controller__btns button:hover{background:rgba(255,255,255,.12)!important}
.replay-player .rr-controller__btns button.active{background:var(--teal)!important;color:var(--text-on-teal)!important}
.replay-player .rr-controller__btns button svg{fill:currentColor;stroke:currentColor}
/* The "skip inactive" toggle: the player's .switch collides with the Kit's .switch (a 46×27 pill with a
   ::after knob), which is what piled the knob onto the words. Undo the Kit rules inside the player and
   give the toggle its own room and colours. */
.replay-player .rr-controller__btns .switch{width:auto!important;height:1em!important;border-radius:0!important;background:none!important;display:flex!important;align-items:center;margin:0 6px 0 10px;transition:none}
.replay-player .rr-controller__btns .switch::after{content:none!important}
.replay-player .rr-controller__btns .switch label{width:2em;height:1em;position:relative;cursor:pointer;display:block;margin:0}
.replay-player .rr-controller__btns .switch label:before{background:rgba(255,255,255,.35)!important}
.replay-player .rr-controller__btns .switch input[type=checkbox]:checked+label:before{background:var(--teal)!important}
.replay-player .rr-controller__btns .switch .label{white-space:nowrap;font-size:12px;color:var(--text-on-navy);margin:0 0 0 10px;letter-spacing:.02em}
/* The replayed page must not react to the viewer's mouse; rrweb draws the recorded cursor itself. */
.replay-player iframe{pointer-events:none;border:0;background:#fff}
.replay-note{padding:10px var(--s4);font-size:12.5px;color:var(--text-3);border-top:1px solid var(--border)}
/* The journey rail is exactly as tall as the player card and scrolls inside. Its content is taken out
   of the grid's height calculation (absolute inside the card) so 60 steps cannot stretch the row; on
   one-column screens, where there is no player beside it, it gets a fixed height instead. */
.replay-steps{position:relative;display:flex;flex-direction:column;height:440px;overflow:hidden}
.replay-steps-inner{display:flex;flex-direction:column;min-height:0;height:100%}
@media(min-width:1100px){
  .replay-layout{align-items:stretch}
  .replay-steps{height:auto;min-height:320px}
  .replay-steps-inner{position:absolute;inset:0}
}
.replay-step-list{flex:1;min-height:0;overflow:auto;padding:var(--s3) var(--s3) var(--s4);display:flex;flex-direction:column;gap:2px}
.replay-step{display:grid;grid-template-columns:44px 74px minmax(0,1fr);gap:8px;align-items:baseline;width:100%;text-align:left;
  padding:7px 8px;border-radius:var(--r-sm);font-size:12.5px;color:var(--text);border-left:3px solid transparent}
.replay-step:hover{background:var(--surface-2)}
.replay-step.active{background:var(--teal-wash);border-left-color:var(--teal)}
.replay-step .rs-time{font-variant-numeric:tabular-nums;color:var(--text-3);font-size:11.5px}
.replay-step .rs-kind{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--text-2)}
.replay-step.kind-nav .rs-kind,.replay-step.kind-load .rs-kind{color:var(--violet-deep)}
.replay-step.kind-submit .rs-kind{color:var(--teal-deep)}
.replay-step .rs-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Person filter on the analytics hub */
.an-range .an-person{min-width:260px;flex:1 1 260px}
.an-person-banner{display:flex;gap:10px;align-items:center;flex-wrap:wrap;background:var(--teal-wash);border:1px solid rgba(22,184,166,.35);border-radius:var(--r-md);padding:10px 14px;margin:0 0 var(--s4);font-size:13.5px;color:var(--text)}
.an-person-banner .linkbtn{margin-left:auto;font-weight:600;color:var(--teal-deep)}
.an-visitor{display:inline-flex;gap:8px;align-items:center;color:inherit}
.an-visitor:hover span:first-child{text-decoration:underline;color:var(--teal-deep)}

.fed-values{display:inline-flex;flex-wrap:wrap;gap:var(--s1);align-items:center}
.fed-legend{margin-top:var(--s3);display:grid;gap:var(--s1);max-width:860px}
.fed-legend p{font-size:13px;color:var(--text-2);margin:0}
.fed-preview{background:var(--surface-2);border:1px solid var(--border-strong);border-radius:var(--r-md);padding:var(--s3) var(--s4);margin:var(--s3) 0}
.fed-preview p{margin:0 0 var(--s2)}
.fed-preview ul{margin:0 0 var(--s2);padding-left:var(--s4)}
.fed-email{border:1px solid var(--border);border-radius:var(--r-md);background:var(--surface);padding:var(--s3) var(--s4);margin-top:var(--s2)}
.fed-recipients{max-height:240px;overflow:auto;border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s2) var(--s3);display:grid;gap:var(--s1);background:var(--surface)}
.fed-fields{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--s3)}
.fed-attrib{font-size:12px;color:var(--text-2)}
.fed-rowmap{display:flex;gap:var(--s1);align-items:center;flex-wrap:wrap}
.fed-rowmap input[type=text]{min-width:180px}
.tbl tr.fed-state-row{background:var(--surface-2)}
.fed-import-section{margin-top:var(--s3)}
.fed-import-section h3{font-size:14px;font-weight:600;margin:0 0 var(--s1)}
.fed-import-section ul{margin:0;padding-left:var(--s4);font-size:13px}
.privacy-note{font-size:13px;color:var(--text-2);margin:var(--s2) 0 0;line-height:1.5}

.prpt-page{min-height:100dvh;background:var(--surface-2);color:var(--text)}
.prpt-top{background:var(--navy);padding:var(--s4) var(--s5)}
.prpt-logo{height:44px;width:auto}
.prpt-main{max-width:1280px;margin:0 auto;padding:var(--s5) var(--s5) var(--s8)}
.prpt-eyebrow{font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--teal-deep);margin:0}
.prpt-head h1{font-size:30px;line-height:1.25;margin:var(--s1) 0 var(--s2);color:var(--navy)}
.prpt-meta{color:var(--text-2);margin:0;font-size:15px}
.prpt-intro{font-size:17px;line-height:1.6;max-width:760px;margin:var(--s4) 0}
.prpt-test{background:var(--amber-wash);border:1px solid var(--amber);border-radius:var(--r-md);padding:var(--s2) var(--s3);margin:var(--s3) 0 0;font-size:14px}
.prpt-actions{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;margin:var(--s4) 0}
.prpt-actions label{font-weight:600;font-size:15px}
.prpt-actions select{font:inherit;font-size:16px;padding:8px 10px;border:1.5px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text)}
.prpt-btn{display:inline-flex;align-items:center;font:inherit;font-size:15px;font-weight:600;padding:8px 16px;border-radius:var(--r-sm);border:1.5px solid var(--navy);background:var(--navy);color:var(--surface);cursor:pointer;text-decoration:none}
.prpt-btn-quiet{background:var(--surface);color:var(--navy)}
.prpt-btn:focus-visible,.prpt-actions select:focus-visible,.prpt-tablewrap:focus-visible,.prpt-table a:focus-visible,.prpt-foot a:focus-visible,.prpt-message a:focus-visible{outline:3px solid var(--teal);outline-offset:2px}
.prpt-tablewrap{overflow-x:auto;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md)}
.prpt-table{width:100%;border-collapse:collapse;font-size:15px}
.prpt-table caption{text-align:left;padding:var(--s3) var(--s4);font-weight:600;color:var(--text)}
.prpt-table thead th{text-align:left;font-size:13px;font-weight:700;color:var(--text);background:var(--surface-2);padding:10px 14px;border-bottom:2px solid var(--border-strong);white-space:nowrap}
.prpt-table tbody th{text-align:left;font-weight:600;padding:10px 14px;border-bottom:1px solid var(--border);vertical-align:top}
.prpt-table td{padding:10px 14px;border-bottom:1px solid var(--border);vertical-align:top}
.prpt-table a{color:var(--teal-deep)}
.prpt-table .prpt-bio{min-width:260px;max-width:420px}
.prpt-empty{font-size:16px;margin:var(--s4) 0}
.prpt-foot{margin-top:var(--s5);max-width:760px;color:var(--text-2);font-size:14px;line-height:1.6}
.prpt-foot a,.prpt-message a{color:var(--teal-deep)}
.prpt-message{max-width:620px;margin:var(--s6) auto;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s5)}
.prpt-message h1{font-size:24px;margin:0 0 var(--s3);color:var(--navy)}
@media print{
  .prpt-top,.prpt-actions{display:none}
  .prpt-page{background:none}
  .prpt-main{padding:0;max-width:none}
  .prpt-tablewrap{overflow:visible;border:none}
  .prpt-table{font-size:11px}
  .prpt-table td,.prpt-table th{padding:4px 6px}
}
.fed-fellowship{display:inline-flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.fed-fellowship-label{font-size:14px;font-weight:600;color:var(--text)}
.fed-fellowship-picker{display:block;width:min(100%,380px)}
.ta-opt.ta-create{font-weight:600;color:var(--teal-deep);border-bottom:1px solid var(--border)}
.fed-target{display:block;width:min(100%,240px)}
.fed-target-wide{width:min(100%,380px)}
