:root{--teal:#0B3A39;--coral:#E87D49;--cream:#F6F6EE;--gold:#D0942F;--yellow:#E4C700;--black:#000;--white:#fff;--teal2:#134f4d;--cream2:#eeede5;--peach:#fde8dc;--sidebar:232px;--topbar:54px;--sh:0 2px 10px rgba(11,58,57,.09)}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;font-family:'Barlow',sans-serif;font-size:14px;background:var(--cream);color:var(--black)}
button,input,textarea,select{font-family:inherit}
::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-thumb{background:rgba(11,58,57,.18);border-radius:10px}
#login-screen{position:fixed;inset:0;background:var(--teal);display:flex;align-items:center;justify-content:center;z-index:9999}
.login-box{background:#fff;border-radius:16px;padding:36px 40px;width:400px;max-width:95vw;text-align:center}
.login-logo-img{height:60px;width:auto;margin-bottom:20px}
.login-sub{font-family:'Barlow Condensed',sans-serif;font-size:10px;letter-spacing:2.5px;text-transform:uppercase;color:rgba(0,0,0,.35);margin-bottom:26px}
.login-lbl{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:rgba(0,0,0,.6);text-align:left;display:block;margin-bottom:4px}
.login-sel,.login-pin{width:100%;border:1.5px solid rgba(0,0,0,.12);border-radius:8px;padding:10px 12px;font-size:14px;margin-bottom:14px;background:var(--cream);outline:none;transition:border .15s}
.login-sel:focus,.login-pin:focus{border-color:var(--teal)}
.login-btn{width:100%;background:var(--coral);color:#fff;border:none;border-radius:8px;padding:12px;font-family:'Barlow Condensed',sans-serif;font-size:15px;font-weight:800;letter-spacing:.5px;cursor:pointer;transition:background .15s}
.login-btn:hover{background:#c96935}
.login-err{color:#c0392b;font-size:11px;margin-bottom:8px;min-height:14px}
#sidebar{position:fixed;top:0;left:0;bottom:0;width:var(--sidebar);background:var(--teal);display:flex;flex-direction:column;z-index:200;box-shadow:3px 0 16px rgba(0,0,0,.14);overflow-y:auto}
.sb-logo{padding:14px 14px 12px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;align-items:center}
.sb-logo-img{height:41px;width:auto}
.sb-grp{margin:2px 0}
.sb-grp-hd{display:flex;align-items:center;justify-content:space-between;padding:8px 13px 6px;cursor:pointer;font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:800;letter-spacing:2px;text-transform:uppercase;color:rgba(255,255,255,.45);user-select:none;transition:color .13s}
.sb-grp-hd:hover{color:rgba(255,255,255,.7)}
.sb-grp-arr{font-size:14px;transition:transform .2s;display:inline-block}
.sb-grp-body{overflow:hidden;transition:max-height .25s ease}
.sb-grp-body.collapsed{max-height:0!important}
.ni{display:flex;align-items:center;gap:8px;padding:8px 13px;cursor:pointer;color:rgba(255,255,255,.78);font-family:'Barlow Condensed',sans-serif;font-size:14px;font-weight:600;letter-spacing:.3px;transition:all .13s;border-left:3px solid transparent;margin:1px 0;user-select:none}
.ni:hover{background:rgba(255,255,255,.06);color:#fff}
.ni.active{background:rgba(232,125,73,.18);color:var(--coral);border-left-color:var(--coral)}
/* .hidden only ever existed for nav items, so every card and button marked
   `nav-admin hidden` was visible to everyone. The data behind them is still
   protected by RLS, but a member could read the webhook URLs and the
   notification settings off the screen. No !important: several admin
   controls reveal themselves with an inline display value and must keep
   winning over this. */
.hidden{display:none}
.ni.hidden{display:none!important}
.nb{margin-left:auto;background:var(--coral);color:#fff;font-size:9px;font-weight:700;border-radius:20px;padding:1px 6px;min-width:16px;text-align:center}
.sb-foot{margin-top:auto;padding:12px 14px;border-top:1px solid rgba(255,255,255,.07);font-size:10px;color:rgba(255,255,255,.22);font-family:'Barlow Condensed',sans-serif}
.sb-av{display:flex;align-items:center;gap:7px;margin-bottom:5px}
.av-c{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:800;color:#fff;font-family:'Barlow Condensed',sans-serif;flex-shrink:0;overflow:hidden}
.av-c img{width:100%;height:100%;object-fit:cover}
#topbar{position:fixed;top:0;left:var(--sidebar);right:0;height:var(--topbar);background:#fff;border-bottom:1px solid rgba(0,0,0,.07);display:flex;align-items:center;padding:0 20px;gap:10px;z-index:100;box-shadow:0 1px 4px rgba(0,0,0,.04)}
.tb-title{font-family:'Barlow Condensed',sans-serif;font-size:18px;font-weight:800;color:var(--teal)}
.tb-r{margin-left:auto;display:flex;align-items:center;gap:7px}
.tb-user{font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:700;color:rgba(0,0,0,.55)}
#main{margin-left:var(--sidebar);padding-top:var(--topbar);min-height:100vh}
.page{padding:18px 20px;display:none}.page.active{display:block}
.btn{display:inline-flex;align-items:center;gap:5px;padding:6px 13px;border-radius:7px;font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:700;letter-spacing:.3px;border:none;cursor:pointer;transition:all .13s;white-space:nowrap}
.btn-p{background:var(--coral);color:#fff}.btn-p:hover{background:#c96935}
.btn-t{background:var(--teal);color:#fff}.btn-t:hover{background:var(--teal2)}
.btn-o{background:transparent;color:var(--teal);border:1.5px solid var(--teal)}.btn-o:hover{background:var(--teal);color:#fff}
.btn-g{background:transparent;color:rgba(0,0,0,.45);border:1.5px solid rgba(0,0,0,.12)}.btn-g:hover{border-color:var(--teal);color:var(--teal)}
.btn-grn{background:#0B3A39;color:#fff}.btn-grn:hover{background:#0d4544}
.btn-red{background:#c0392b;color:#fff}.btn-red:hover{background:#a93226}
.btn-gold{background:var(--gold);color:#fff}.btn-gold:hover{background:#b07a20}
.btn-sm{padding:4px 10px;font-size:11px}.btn-xs{padding:2px 7px;font-size:10px}
.card{background:#fff;border-radius:11px;box-shadow:var(--sh);overflow:hidden}
.ch{padding:12px 16px;border-bottom:1px solid rgba(0,0,0,.05);display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}
.ct{font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:800;letter-spacing:1.5px;text-transform:uppercase;color:var(--teal)}
.cb{padding:14px 16px}
.srow{display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:10px;margin-bottom:16px}
.sc{background:#fff;border-radius:11px;padding:14px 16px;box-shadow:var(--sh);border-top:4px solid var(--teal);cursor:pointer;transition:transform .12s,box-shadow .12s}
.sc:hover{transform:translateY(-1px);box-shadow:0 4px 14px rgba(11,58,57,.13)}
.sc.cor{border-top-color:var(--coral)}.sc.gld{border-top-color:var(--gold)}.sc.yel{border-top-color:var(--yellow)}.sc.grn{border-top-color:#0B3A39}
.sl{font-family:'Barlow Condensed',sans-serif;font-size:9px;letter-spacing:2px;text-transform:uppercase;color:rgba(0,0,0,.35);margin-bottom:3px}
.sv{font-family:'Barlow Condensed',sans-serif;font-size:30px;font-weight:800;color:var(--teal);line-height:1}
.ss{font-size:10px;color:rgba(0,0,0,.3);margin-top:2px}
.bdg{display:inline-flex;align-items:center;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:700;font-family:'Barlow Condensed',sans-serif;letter-spacing:.3px;text-transform:uppercase;white-space:nowrap}
.b-teal{background:rgba(11,58,57,.1);color:var(--teal)}.b-coral{background:rgba(232,125,73,.15);color:#b05a28}
.b-gold{background:rgba(208,148,47,.15);color:#8a6010}.b-yel{background:rgba(228,199,0,.2);color:#7a6a00}
.b-grn{background:rgba(11,58,57,.12);color:#0B3A39}.b-red{background:rgba(192,57,43,.1);color:#c0392b}
.b-gray{background:rgba(0,0,0,.07);color:rgba(0,0,0,.45)}.b-pur{background:rgba(142,68,173,.12);color:#6c3483}
.b-blue{background:rgba(41,128,185,.12);color:#1a5276}.b-pink{background:rgba(231,76,60,.1);color:#922b21}
.tbl{width:100%;border-collapse:collapse}
.tbl th{padding:8px 12px;text-align:left;font-family:'Barlow Condensed',sans-serif;font-size:9px;letter-spacing:1.5px;text-transform:uppercase;color:rgba(0,0,0,.55);border-bottom:2px solid rgba(0,0,0,.06);white-space:nowrap}
.tbl td{padding:9px 12px;border-bottom:1px solid rgba(0,0,0,.045);font-size:13px;vertical-align:middle}
.tbl tr:last-child td{border-bottom:none}
.tbl tbody tr:hover td{background:rgba(11,58,57,.022)}
.mov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:500;align-items:center;justify-content:center}
.mov.open{display:flex}
.modal{background:#fff;border-radius:13px;width:580px;max-width:96vw;max-height:92vh;display:flex;flex-direction:column;box-shadow:0 20px 60px rgba(0,0,0,.22)}
.mb{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 20px 16px}
.mh{flex-shrink:0;padding:18px 20px 12px;border-bottom:1px solid rgba(0,0,0,.06)}
.mf{flex-shrink:0;padding:12px 20px;border-top:1px solid rgba(0,0,0,.07);display:flex;gap:8px;justify-content:flex-end;background:#fff}
.modal.wide{width:700px}.modal.narrow{width:440px}
.mh{padding:16px 20px 12px;border-bottom:1px solid rgba(0,0,0,.07);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:#fff}
.mt{font-family:'Barlow Condensed',sans-serif;font-size:16px;font-weight:800;color:var(--teal)}
.mc{background:none;border:none;font-size:20px;cursor:pointer;color:rgba(0,0,0,.3);line-height:1;padding:4px 8px;min-height:32px}.mc:hover{color:var(--black)}
.fr{display:grid;grid-template-columns:1fr 1fr;gap:11px;margin-bottom:11px}
.fr.full{grid-template-columns:1fr}.fr.tri{grid-template-columns:1fr 1fr 1fr}
.fg{display:flex;flex-direction:column;gap:4px}
.fl{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:rgba(0,0,0,.6)}
.fi,.fs,.fta{border:1.5px solid rgba(0,0,0,.11);border-radius:7px;padding:7px 10px;font-size:12px;background:var(--cream);transition:border .13s;outline:none}
.fi:focus,.fs:focus,.fta:focus{border-color:var(--teal)}
.fta{resize:vertical;min-height:60px}
.fs{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='6'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 9px center;padding-right:28px}
.multi-check{display:flex;flex-wrap:wrap;gap:5px;margin-top:3px}
.multi-check label{display:flex;align-items:center;gap:4px;font-size:11px;padding:3px 9px;border-radius:20px;border:1.5px solid rgba(0,0,0,.12);cursor:pointer;transition:all .13s}
.multi-check label:hover{border-color:var(--teal)}
.multi-check input[type=checkbox]{display:none}
.multi-check label:has(input:checked){background:var(--teal);border-color:var(--teal);color:#fff}
.pipe-scroll{display:flex;gap:10px;overflow-x:auto;padding-bottom:8px}
.pipe-col{min-width:205px;max-width:205px;background:rgba(0,0,0,.03);border-radius:10px;padding:10px}
.pch{display:flex;align-items:center;justify-content:space-between;margin-bottom:7px}
.psl{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:800;letter-spacing:.8px;text-transform:uppercase}
.psc{font-size:9px;background:rgba(0,0,0,.09);border-radius:20px;padding:1px 6px;font-weight:700}
.dc{background:#fff;border-radius:7px;padding:9px;margin-bottom:5px;box-shadow:0 1px 3px rgba(0,0,0,.07);cursor:pointer;border-left:3px solid var(--teal);transition:transform .1s}
.dc:hover{transform:translateY(-1px)}
.dn{font-weight:600;font-size:12px;margin-bottom:2px}
.dm{font-size:10px;color:rgba(0,0,0,.38);display:flex;justify-content:space-between}
.task-item{padding:9px 11px;border-radius:7px;background:var(--cream);margin-bottom:5px;cursor:pointer;transition:background .1s}
.task-item:hover{background:var(--cream2)}
.task-item.high-priority{background:var(--peach);border-left:3px solid var(--coral)}
.task-item-name{font-size:12px;font-weight:600;margin-bottom:3px}
.task-item-meta{font-size:10px;color:rgba(0,0,0,.55);display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.task-due-alert{color:#c0392b;font-weight:700}
.del-sec{margin-bottom:14px}
.dsec-t{font-family:'Barlow Condensed',sans-serif;font-size:9px;font-weight:800;letter-spacing:1.5px;text-transform:uppercase;color:rgba(0,0,0,.35);margin-bottom:5px;padding-bottom:3px;border-bottom:1px solid rgba(0,0,0,.06)}
.dr{display:flex;align-items:center;gap:7px;padding:6px 9px;border-radius:6px;margin-bottom:3px;background:var(--cream);transition:background .1s}
.dr:hover{background:var(--cream2)}
.dr.high-priority{background:var(--peach)}
.dck{width:14px;height:14px;border-radius:3px;border:2px solid rgba(0,0,0,.18);cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:all .13s}
.dck.done{background:var(--teal);border-color:var(--teal)}
.dck.done::after{content:"";color:#fff;font-size:8px;font-weight:700}
.dname{flex:1;font-size:11px}.dname.done{text-decoration:line-through;color:rgba(0,0,0,.32)}
.cmt-thread{border:1.5px solid rgba(0,0,0,.08);border-radius:9px;overflow:hidden;margin-top:8px}
.cmt-list{max-height:160px;overflow-y:auto;padding:8px 11px}
.cmt-it{display:flex;gap:7px;margin-bottom:9px}
.cav{width:24px;height:24px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:800;font-family:'Barlow Condensed',sans-serif;color:#fff;overflow:hidden}
.cav img{width:100%;height:100%;object-fit:cover}
.cnm{font-size:10px;font-weight:700;color:var(--teal);margin-bottom:1px}
.ctx{font-size:11px;color:rgba(0,0,0,.65);line-height:1.4}
.ctx .mention{color:var(--coral);font-weight:700}
.ctm{font-size:9px;color:rgba(0,0,0,.28)}
.cin-wrap{position:relative}
.cin-row{display:flex;gap:6px;padding:7px 9px;border-top:1px solid rgba(0,0,0,.06);background:var(--cream)}
.cin-row input{flex:1;border:1.5px solid rgba(0,0,0,.1);border-radius:6px;padding:5px 8px;font-size:11px;outline:none;background:#fff}
.cin-row input:focus{border-color:var(--teal)}
.mention-dropdown{position:fixed;background:#fff;border:1.5px solid rgba(0,0,0,.1);border-radius:7px;box-shadow:0 4px 20px rgba(0,0,0,.22);z-index:9000;display:none;min-width:180px;max-height:220px;overflow-y:auto}
.mention-item{padding:7px 12px;cursor:pointer;font-size:12px;display:flex;align-items:center;gap:7px;transition:background .1s}
.mention-item:hover{background:var(--cream)}
.mention-item .mi-av{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:8px;font-weight:800;color:#fff;font-family:'Barlow Condensed',sans-serif;flex-shrink:0;overflow:hidden}
.mention-item .mi-av img{width:100%;height:100%;object-fit:cover}
.pw{height:5px;background:rgba(0,0,0,.07);border-radius:10px;overflow:hidden}
.pf{height:100%;border-radius:10px;background:var(--teal)}
.tabs{display:flex;gap:2px;border-bottom:2px solid rgba(0,0,0,.06);margin-bottom:14px;flex-wrap:wrap}
.tab{padding:6px 13px;font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:700;letter-spacing:.3px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;color:rgba(0,0,0,.38);transition:all .13s}
.tab.active{color:var(--teal);border-bottom-color:var(--teal)}
.tp{display:none}.tp.active{display:block}
.sh{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;flex-wrap:wrap;gap:8px}
.st{font-family:'Barlow Condensed',sans-serif;font-size:14px;font-weight:800;letter-spacing:.4px;color:var(--teal)}
.vid-card{background:#fff;border-radius:10px;box-shadow:var(--sh);padding:13px 15px;margin-bottom:10px}
.vid-top{display:flex;align-items:start;justify-content:space-between;margin-bottom:10px}
.vid-client-name{font-family:'Barlow Condensed',sans-serif;font-size:15px;font-weight:800;color:var(--teal)}
.vid-row{display:flex;align-items:flex-start;gap:7px;padding:5px 0;border-bottom:1px solid rgba(0,0,0,.045);font-size:11px}
.vid-row:last-child{border-bottom:none}
.vid-lbl{color:rgba(0,0,0,.38);width:95px;flex-shrink:0;font-family:'Barlow Condensed',sans-serif;font-weight:600;font-size:10px;padding-top:1px}
.vid-val{flex:1}
.tgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:11px}
.tc{background:#fff;border-radius:10px;padding:13px 15px;box-shadow:var(--sh)}
.tch{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.tav{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:'Barlow Condensed',sans-serif;font-size:14px;font-weight:800;color:#fff;flex-shrink:0;overflow:hidden}
.tav img{width:100%;height:100%;object-fit:cover}
.tn{font-family:'Barlow Condensed',sans-serif;font-size:13px;font-weight:800;color:var(--teal)}
.trole{font-size:10px;color:rgba(0,0,0,.38)}
.wb{height:5px;background:rgba(0,0,0,.07);border-radius:10px;overflow:hidden;margin:5px 0 3px}
.wf{height:100%;border-radius:10px}
.tpill{display:flex;align-items:center;justify-content:space-between;padding:5px 7px;background:var(--cream);border-radius:6px;margin-bottom:3px;font-size:11px;cursor:pointer;transition:background .1s}
.tpill:hover{background:var(--cream2)}
.p-banner{background:var(--teal);color:#fff;padding:16px 20px;border-radius:10px;margin-bottom:14px;display:flex;align-items:center;gap:12px}
.p-logo{height:32px;width:auto}
.p-cn{font-family:'Barlow Condensed',sans-serif;font-size:20px;font-weight:800;margin-bottom:1px}
.res-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
.res-card{background:#fff;border-radius:9px;box-shadow:var(--sh);overflow:hidden;transition:transform .12s}
.res-card:hover{transform:translateY(-2px)}
.res-thumb{height:120px;display:flex;align-items:center;justify-content:center;background:rgba(11,58,57,.05);cursor:pointer;overflow:hidden}
.res-thumb img{width:100%;height:100%;object-fit:cover}
.res-thumb .res-icon{font-size:36px}
.res-info{padding:10px 12px;border-top:1px solid rgba(0,0,0,.05)}
.res-name{font-size:12px;font-weight:700;margin-bottom:2px;font-family:'Barlow Condensed',sans-serif}
.res-meta{font-size:10px;color:rgba(0,0,0,.35)}
.es{text-align:center;padding:24px;color:rgba(0,0,0,.3);font-size:11px}
.es p{margin-top:6px}
.rl{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;margin-bottom:4px;cursor:pointer;transition:background .1s}
.rl:hover{background:rgba(0,0,0,.03)}
.rd{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.ri{flex:1;min-width:0}
.rn{font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rs{font-size:10px;color:rgba(0,0,0,.38)}
.rv{font-size:11px;font-weight:700;color:var(--teal);white-space:nowrap}
.rdt{font-size:10px;color:rgba(0,0,0,.4);white-space:nowrap}
.wh-ban{background:rgba(11,58,57,.06);border:1px solid rgba(11,58,57,.12);border-radius:8px;padding:10px 14px;margin-bottom:12px;font-size:11px;display:flex;align-items:flex-start;gap:9px;line-height:1.5}
.wh-ban code{font-size:10px;background:rgba(0,0,0,.07);padding:1px 5px;border-radius:4px}
.slack-toast{position:fixed;bottom:20px;right:20px;background:var(--teal);color:#fff;padding:12px 16px;border-radius:9px;font-size:12px;line-height:1.5;z-index:9999;box-shadow:0 4px 16px rgba(0,0,0,.22);animation:slideIn .3s ease;max-width:320px}
.su-entry{padding:8px 0;border-bottom:1px solid rgba(0,0,0,.06);display:flex;gap:8px;align-items:flex-start}
.su-entry:last-child{border-bottom:none}
.su-meta{font-size:10px;color:rgba(0,0,0,.4);margin-bottom:3px;display:flex;gap:6px;align-items:center}
.su-author{font-weight:700;color:var(--teal);font-family:'Barlow Condensed',sans-serif;font-size:11px}
.su-text{font-size:12px;color:#333;line-height:1.5}
.su-status-snap{font-size:9px;font-weight:700;padding:1px 6px;border-radius:4px;background:rgba(0,0,0,.07);font-family:'Barlow Condensed',sans-serif;letter-spacing:.5px;text-transform:uppercase}
.stale-badge{background:var(--coral);color:#fff;border-radius:6px;padding:2px 7px;font-size:10px;font-weight:700;font-family:'Barlow Condensed',sans-serif}
@keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}
.loading-overlay{position:fixed;inset:0;background:rgba(255,255,255,.85);display:flex;align-items:center;justify-content:center;z-index:8000;font-family:'Barlow Condensed',sans-serif;font-size:14px;font-weight:700;color:var(--teal);letter-spacing:1px;gap:10px}
.sync-dot{width:8px;height:8px;border-radius:50%;background:var(--coral);display:inline-block;animation:pulse 1.2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.2}}
.review-card{background:#fff;border-radius:10px;box-shadow:var(--sh);padding:14px 16px;margin-bottom:10px;border-left:4px solid var(--gold)}
.review-card.revision{border-left-color:var(--coral)}
.review-card-title{font-family:'Barlow Condensed',sans-serif;font-size:13px;font-weight:800;color:var(--teal);margin-bottom:4px}
.review-card-meta{font-size:10px;color:rgba(0,0,0,.4);margin-bottom:8px}
.filter-bar{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;align-items:center}
.filter-bar .fs{min-width:120px;font-size:11px;padding:5px 28px 5px 8px}
.rec-submit-btn{background:var(--gold);color:#fff;border:none;border-radius:6px;padding:4px 10px;font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;cursor:pointer;transition:background .13s}
.rec-submit-btn:hover{background:#b07a20}
.rec-submitted-lbl{font-size:10px;color:#0B3A39;font-weight:700;font-family:'Barlow Condensed',sans-serif}
.rec-revision-lbl{font-size:10px;color:var(--coral);font-weight:700;font-family:'Barlow Condensed',sans-serif;cursor:pointer}
.rte-wrap{border:1.5px solid rgba(0,0,0,.11);border-radius:7px;overflow:hidden;background:var(--cream)}
.rte-wrap:focus-within{border-color:var(--teal)}
.rte-toolbar{display:flex;gap:2px;padding:5px 7px;background:#fff;border-bottom:1px solid rgba(0,0,0,.08);flex-wrap:wrap}
.rte-btn{background:none;border:none;border-radius:4px;padding:3px 7px;font-size:12px;cursor:pointer;color:rgba(0,0,0,.55);font-family:'Barlow',sans-serif;transition:background .1s;line-height:1}
.rte-btn:hover{background:rgba(0,0,0,.07);color:var(--black)}
.rte-btn.active{background:var(--teal);color:#fff}
.rte-field{min-height:90px;padding:8px 10px;font-size:12px;font-family:'Barlow',sans-serif;outline:none;line-height:1.6;color:var(--black)}
.rte-field a{color:var(--teal);text-decoration:underline}
.rte-field:empty:before{content:attr(data-placeholder);color:rgba(0,0,0,.3);pointer-events:none}
.rte-sep{width:1px;background:rgba(0,0,0,.1);margin:2px 3px;align-self:stretch}

/*  MOBILE  */
.hamburger{display:none;position:fixed;top:11px;left:12px;z-index:9001;background:transparent;border:none;cursor:pointer;padding:4px;flex-direction:column;gap:5px}
.hamburger span{display:block;width:22px;height:2px;background:var(--teal);border-radius:2px;transition:all .2s}
.mob-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:8999}
.mob-overlay.open{display:block}
.mob-nav{display:none;position:fixed;bottom:0;left:0;right:0;height:56px;background:var(--teal);z-index:300;border-top:1px solid rgba(255,255,255,.1);box-shadow:0 -2px 12px rgba(0,0,0,.2)}
.mob-nav-inner{display:flex;height:100%}
.mob-nb{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;color:rgba(255,255,255,.5);font-family:'Barlow Condensed',sans-serif;font-size:8px;letter-spacing:.5px;text-transform:uppercase;gap:2px;transition:color .15s;padding:0}
.mob-nb.active{color:var(--yellow)}
.mob-nb svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

@media(max-width:768px){
  :root{--sidebar:0px;--topbar:50px}
  /* Hamburger, above everything including modals overlay */
  .hamburger{display:flex;z-index:9100}
  #sidebar{transform:translateX(-260px);transition:transform .25s ease;width:280px!important;z-index:9000;overflow-y:auto}
  #sidebar.mob-open{transform:translateX(0)}
  #topbar{left:0;padding:0 12px 0 58px}
  .tb-title{font-size:14px;padding-left:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:55vw}
  .tb-user{display:none}
  #main{margin-left:0;padding-top:var(--topbar)}
  .page{padding:12px 12px 100px}
  .srow{grid-template-columns:1fr 1fr!important}
  .pipe-col{min-width:220px}
  .tbl{min-width:480px;font-size:11px}
  .tbl td,.tbl th{padding:7px 8px}
  /* Modals, slide up from bottom */
  .mov.open{align-items:flex-end!important}
  .modal,.modal.wide,.modal.narrow{
    width:100vw!important;max-width:100vw!important;
    border-radius:16px 16px 0 0!important;
    position:fixed!important;bottom:0!important;top:auto!important;left:0!important;
    max-height:88vh!important;display:flex;flex-direction:column;
  }
  /* Modal body scrolls, header and footer stay fixed */
  .mh{flex-shrink:0}
  .mb{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:8px}
  .mf{
    flex-shrink:0;
    position:sticky;bottom:0;
    background:#fff;
    z-index:10;
    padding:12px 20px 28px; /* extra bottom padding for home indicator */
    border-top:1px solid rgba(0,0,0,.08);
    display:flex;gap:8px;justify-content:flex-end;
    box-shadow:0 -4px 16px rgba(0,0,0,.06);
  }
  /* Buttons, minimum 44px touch targets */
  .btn{min-height:36px;padding:8px 14px}
  .btn-sm{min-height:34px}
  .btn-xs{min-height:28px;padding:4px 10px;font-size:10px}
  /* Form fields, bigger on mobile */
  .fi,.fs,.fta{font-size:16px!important} /* prevents iOS zoom */
  .fr,.fr.tri{grid-template-columns:1fr!important}
  .login-box{padding:28px 20px;width:95vw}
  .tgrid{grid-template-columns:1fr!important}
  .res-grid{grid-template-columns:1fr 1fr!important}
  .filter-bar{flex-wrap:wrap;gap:6px}
  .filter-bar .fs,.filter-bar .fi{flex:1;min-width:120px}
  .mob-nav{display:block}
  .sc{padding:10px 12px}
  .sv{font-size:22px}
  .sh{flex-wrap:wrap;gap:6px}
  .sh .btn{font-size:11px}
  /* Card layout improvements */
  .vid-card{padding:12px}
  .card{padding:0}
  .cb{padding:10px 12px!important}
  /* Tabs, scrollable on mobile */
  .tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;flex-wrap:nowrap;padding-bottom:2px}
  .tab{white-space:nowrap;flex-shrink:0}
}
@media(max-width:400px){
  .srow{grid-template-columns:1fr!important}
  .res-grid{grid-template-columns:1fr!important}
  .tabs{gap:0}
  .tab{padding:5px 9px;font-size:11px}
  .tb-title{max-width:45vw}
}

/* ── MOBILE POLISH (v8-4), CSS only ── */
@media(max-width:768px){
  /* Problem 1: top-bar action buttons crowding the title.
     Shrink them and let the row stay tidy. */
  #topbar{gap:6px}
  .tb-r{gap:6px;flex-shrink:0}
  .tb-r .btn,.tb-r .btn-sm{
    min-height:32px;padding:6px 10px;font-size:11px;white-space:nowrap;
  }
  .tb-title{max-width:42vw}

  /* Problem 2: stat cards cramped 2-up on mid-size phones.
     Let them auto-fit so they go 1-up when space is tight, 2-up when there's room. */
  .srow{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))!important}
  .sc{padding:12px 14px}
  .sv{font-size:24px}

  /* Problem 3: bottom nav overlapping content + iOS home indicator.
     Clear the 56px nav plus the safe-area inset. */
  .page{padding-bottom:calc(76px + env(safe-area-inset-bottom,0px))!important}
  .mob-nav{height:calc(56px + env(safe-area-inset-bottom,0px));padding-bottom:env(safe-area-inset-bottom,0px)}

  /* Two top-bar buttons side by side can still be tight on the smallest phones;
     allow them to wrap under the title row gracefully rather than overflow. */
  #topbar{flex-wrap:nowrap}
}
@media(max-width:380px){
  /* Smallest phones: stack stat cards fully and trim button text room. */
  .srow{grid-template-columns:1fr!important}
  .tb-r .btn,.tb-r .btn-sm{padding:6px 8px;font-size:10px}
  .tb-title{max-width:38vw;font-size:13px}
}

/* ===== Mobile polish pass (appended; later rules override earlier ones) ===== */
@media(max-width:768px){
  /* Sidebar was translateX(-260px) but is 280px wide, leaving a 20px strip
     bleeding over every page. Hide it fully. */
  #sidebar{transform:translateX(-100%)!important}
  #sidebar.mob-open{transform:translateX(0)!important}

  /* Some list tables (e.g. Clients) sit directly in a .card, which has
     overflow:hidden, so their wider columns were clipped with no way to scroll.
     Let cards scroll horizontally on mobile so every column is reachable. */
  .card{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* Give scrollable tables a hint of the swipe with a little inertia room. */
  .tbl{min-width:520px}

  /* Header rows with more than one control group (e.g. the pipeline tabs plus
     action buttons) wrap cleanly instead of crowding or overflowing. */
  .sh{align-items:stretch}
  .sh > div{min-width:0}
  #pipe-tabs{flex-wrap:wrap}

  /* Modal footers that carry extra actions (Archive / Delete on the lead modal)
     wrap rather than overflow off the edge. */
  .mf{flex-wrap:wrap}
  .mf > div{flex-wrap:wrap}
}

/* Failed write notice. Coral because a lost write is a real failure, not a
   warning. Sits above the Slack toast so both can show at once. */
.write-err-toast{position:fixed;bottom:20px;left:20px;background:var(--coral);color:#fff;padding:13px 17px;border-radius:9px;font-size:12px;line-height:1.5;z-index:10000;box-shadow:0 4px 16px rgba(0,0,0,.28);animation:slideIn .3s ease;max-width:340px}
.write-err-toast strong{font-family:'Barlow Condensed',sans-serif;font-size:14px;letter-spacing:.5px;text-transform:uppercase}
@media(max-width:640px){.write-err-toast{left:12px;right:12px;bottom:76px;max-width:none}}

/* Saved but incomplete: a column the table does not have was dropped so the
   rest of the record could be stored. Gold because it needs attention, not
   coral, which is reserved for an actual failure. */
.write-warn-toast{position:fixed;bottom:20px;left:20px;background:var(--gold);color:#fff;padding:13px 17px;border-radius:9px;font-size:12px;line-height:1.5;z-index:10000;box-shadow:0 4px 16px rgba(0,0,0,.28);animation:slideIn .3s ease;max-width:340px}
.write-warn-toast strong{font-family:'Barlow Condensed',sans-serif;font-size:14px;letter-spacing:.5px;text-transform:uppercase}
@media(max-width:640px){.write-warn-toast{left:12px;right:12px;bottom:76px;max-width:none}}

/* Notification bell, count badge and dropdown feed. Coral badge because an
   unread item needs attention; unread rows carry a cream wash and a coral rail
   so read and unread are distinguishable without introducing a new colour. */
.notif-wrap{position:relative;display:inline-flex}
.notif-bell{background:transparent;border:none;color:var(--teal);cursor:pointer;padding:5px;display:inline-flex;align-items:center;justify-content:center;border-radius:7px;position:relative}
.notif-bell:hover{background:rgba(11,58,57,.07)}
.notif-count{position:absolute;top:-2px;right:-2px;background:var(--coral);color:#fff;border-radius:9px;min-width:16px;height:16px;padding:0 4px;font-size:9px;font-weight:800;font-family:'Barlow Condensed',sans-serif;display:flex;align-items:center;justify-content:center;line-height:1}
.notif-dd{position:absolute;top:calc(100% + 8px);right:0;width:340px;max-height:420px;overflow-y:auto;background:#fff;border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.18);z-index:9500}
.notif-dd-head{display:flex;align-items:center;justify-content:space-between;padding:11px 14px;border-bottom:1px solid rgba(0,0,0,.08);position:sticky;top:0;background:#fff;border-radius:10px 10px 0 0}
.notif-dd-head span{font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:var(--teal)}
.notif-mark-all{background:transparent;border:none;color:var(--coral);font-size:11px;font-weight:700;cursor:pointer;font-family:'Barlow',sans-serif;padding:0}
.notif-mark-all:hover{text-decoration:underline}
.notif-item{padding:10px 14px;border-bottom:1px solid rgba(0,0,0,.05);cursor:pointer;display:flex;gap:9px;align-items:flex-start}
.notif-item:hover{background:rgba(11,58,57,.04)}
.notif-item.unread{background:var(--cream);border-left:3px solid var(--coral);padding-left:11px}
.notif-item-ttl{font-size:12px;font-weight:700;color:#111;line-height:1.35;margin-bottom:2px}
.notif-item-msg{font-size:11px;color:rgba(0,0,0,.55);line-height:1.4}
.notif-item-time{font-size:10px;color:rgba(0,0,0,.35);margin-top:3px}
.notif-empty{padding:26px 14px;text-align:center;font-size:12px;color:rgba(0,0,0,.35)}
@media(max-width:640px){.notif-dd{position:fixed;top:56px;left:10px;right:10px;width:auto;max-height:70vh}}

/* Transient popup when a notification arrives while the app is open. Teal, so it
   is never confused with the coral failure toast or the gold partial-save one. */
.notif-toast{position:fixed;top:66px;right:20px;background:var(--teal);color:#fff;padding:12px 16px;border-radius:9px;font-size:12px;line-height:1.5;z-index:10001;box-shadow:0 4px 16px rgba(0,0,0,.26);animation:slideIn .3s ease;max-width:320px;cursor:pointer}
.notif-toast strong{font-family:'Barlow Condensed',sans-serif;font-size:13px;letter-spacing:.5px;text-transform:uppercase;display:block;margin-bottom:2px}
@media(max-width:640px){.notif-toast{left:12px;right:12px;top:auto;bottom:76px;max-width:none}}

/* Destructive actions. Outlined coral rather than solid, so a permanent delete
   never sits next to the solid coral Save button looking like the same weight of
   action. Coral is the brand's at-risk / error colour. */
.btn-danger{background:transparent;color:var(--coral);border:1.5px solid var(--coral)}
.btn-danger:hover{background:var(--coral);color:#fff}
/* Archived rows read as inactive without introducing a new colour. */
.row-archived{opacity:.55}

/* ============================================================
   SYSTEM BANNER (appended per the append-don't-overwrite rule)
   An empty page used to be indistinguishable from a failed load, so a refused
   request looked exactly like "you have no clients". These banners sit at the
   top of the workspace and say which it is.
   Coral = the app is not showing you data that exists. Gold = degraded.
   ============================================================ */
.sys-banner{padding:12px 16px;border-radius:9px;margin-bottom:14px;font-size:12.5px;line-height:1.55;color:#fff}
.sys-banner strong{display:block;font-family:'Barlow Condensed',sans-serif;font-size:15px;letter-spacing:.5px;text-transform:uppercase;margin-bottom:3px}
.sys-banner code{background:rgba(255,255,255,.2);padding:1px 5px;border-radius:3px;font-size:11.5px}
.sys-banner-err{background:var(--coral)}
.sys-banner-warn{background:var(--gold)}

/* ============================================================
   DUE DATE CHIP
   The due date used to render in the same muted gray as the client
   name and the assignee, so the one field that decides what gets
   picked up next read as filler. Every dashboard now renders it
   through dueChip(), which colors it by how close the date is.
   Coral = past due. Gold = due today or tomorrow. Teal = still ahead.
   Text tones match the existing .b-coral / .b-gold / .b-teal badges
   so the chip reads as part of the same system.
   ============================================================ */
.due-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:4px;font-family:'Barlow Condensed',sans-serif;font-size:11px;font-weight:700;letter-spacing:.4px;line-height:1.4;white-space:nowrap;vertical-align:middle}
.due-chip::before{content:'DUE';font-size:8.5px;letter-spacing:.7px;opacity:.6}
.due-chip-bare::before{content:none}
.due-over{background:rgba(232,125,73,.18);color:#b05a28}
.due-soon{background:rgba(208,148,47,.18);color:#8a6010}
.due-ok{background:rgba(11,58,57,.09);color:var(--teal)}

/* ============================================================
   OUTREACH STATUS COLOURS
   Every status rendered in the same gray badge meant the pipeline read as one
   flat list and you had to open records to find out where anything stood.
   Colour now carries the state, following the brand rules: teal for on track,
   gold for needs attention, coral for stalled or stopped, yellow where gold is
   already doing work nearby, gray for neutral. The two end states are solid
   rather than tinted, because "won" and "stop" should not look like a step.
   ============================================================ */
.os-new      {background:rgba(0,0,0,.07);color:rgba(0,0,0,.5)}
.os-waiting  {background:rgba(228,199,0,.24);color:#7a6a00}
.os-stalled  {background:rgba(232,125,73,.18);color:#b05a28}
.os-active   {background:rgba(208,148,47,.2);color:#8a6010}
.os-booked   {background:rgba(11,58,57,.12);color:var(--teal)}
.os-won      {background:var(--teal);color:var(--cream)}
.os-closed   {background:rgba(0,0,0,.14);color:rgba(0,0,0,.55)}
.os-stop     {background:var(--coral);color:#fff}
.os-retired  {background:repeating-linear-gradient(45deg,rgba(0,0,0,.05),rgba(0,0,0,.05) 4px,rgba(0,0,0,.1) 4px,rgba(0,0,0,.1) 8px);color:rgba(0,0,0,.5)}
/* Follow-up date sitting beside the status, coral once it is due or past. */
.fu-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:4px;font-family:'Barlow Condensed',sans-serif;font-size:10.5px;font-weight:700;letter-spacing:.4px;white-space:nowrap;background:rgba(11,58,57,.09);color:var(--teal)}
.fu-chip::before{content:'FOLLOW UP';font-size:8px;letter-spacing:.6px;opacity:.6}
.fu-due{background:rgba(232,125,73,.2);color:#b05a28}

/* ============================================================
   FORMATTED NOTES
   Task details and editor notes were single blocks of plain text. A long one
   was a wall, and a link in it could not be clicked. These are the toolbar
   above the field, and the styles for the rendered result.
   ============================================================ */
.md-bar{display:flex;gap:3px;align-items:center;flex-wrap:wrap;margin-bottom:5px}
.md-btn{border:1.5px solid rgba(0,0,0,.12);background:#fff;border-radius:5px;min-width:28px;height:26px;padding:0 7px;cursor:pointer;font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:700;color:var(--teal);line-height:1}
.md-btn:hover{background:var(--cream2);border-color:rgba(11,58,57,.3)}
.md-btn.on{background:var(--teal);color:var(--cream);border-color:var(--teal)}
.md-hint{font-size:10px;color:rgba(0,0,0,.35);margin-left:auto}
.md-preview{border:1.5px solid rgba(0,0,0,.15);border-radius:6px;padding:9px 11px;min-height:90px;background:var(--cream);font-size:13px;line-height:1.6}
/* Shared by the preview and by every read-only place a note is shown. */
.md-body{font-size:13px;line-height:1.6;word-break:break-word}
.md-body ul,.md-body ol{margin:4px 0 4px 18px}
.md-body li{margin-bottom:2px}
.md-body strong{font-weight:700}
.md-body a{color:var(--teal);text-decoration:underline}
.md-body code{background:rgba(0,0,0,.06);padding:1px 4px;border-radius:3px;font-size:12px}
.md-body div{margin-bottom:2px}
.md-body .md-sp{height:6px}
/* A long note must not stretch a card out of shape. Scrolls in place instead. */
.md-clamp{max-height:120px;overflow-y:auto}
/* Comments borrow the markdown styling but keep their own smaller size. */
.ctx.md-body{font-size:11px;line-height:1.5}
.ctx.md-body code{font-size:10.5px}

/* ============================================================
   VIDEO JOB SCOPE
   Five collapsible sections replacing the flat chip row. A collapsed section
   still states what is selected inside it, so the whole scope is readable
   without opening anything.
   ============================================================ */
.vs-sec{border:1.5px solid rgba(0,0,0,.1);border-radius:8px;margin-bottom:8px;background:#fff;overflow:hidden}
.vs-sec.vs-bad{border-color:var(--coral)}
.vs-hd{display:flex;align-items:center;gap:8px;padding:9px 11px;cursor:pointer;user-select:none}
.vs-hd:hover{background:var(--cream)}
.vs-arw{font-size:10px;color:rgba(0,0,0,.35);transition:transform .12s;flex-shrink:0}
.vs-sec.open .vs-arw{transform:rotate(90deg)}
.vs-ttl{font-family:'Barlow Condensed',sans-serif;font-size:11px;font-weight:800;letter-spacing:1.2px;text-transform:uppercase;color:#000;flex-shrink:0}
.vs-req{color:var(--coral);margin-left:-5px}
.vs-sum{font-size:11px;color:rgba(0,0,0,.45);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;text-align:right}
.vs-sum.none{color:rgba(0,0,0,.28);font-style:italic}
.vs-bd{padding:2px 11px 11px;display:none;flex-wrap:wrap;gap:6px}
.vs-sec.open .vs-bd{display:flex}
/* Chips. Black fill when on, so selection reads at a glance and colour is
   reserved for video type. No teal in this panel at all, by request. */
.vs-chip{display:inline-flex;align-items:center;gap:6px;border:1.5px solid rgba(0,0,0,.13);background:#fff;border-radius:20px;padding:5px 12px;cursor:pointer;font-size:12px;line-height:1.2;transition:background .1s,border-color .1s}
.vs-chip:hover{border-color:rgba(0,0,0,.35);background:var(--cream)}
.vs-chip.on{background:#000;border-color:#000;color:var(--cream);font-weight:600}
.vs-chip.on:hover{background:#2b2b2b}
/* Number stepper, only on a selected counted deliverable. */
.vs-cnt{display:inline-flex;align-items:center;gap:0;margin-left:2px}
.vs-cnt button{width:19px;height:19px;border:none;border-radius:4px;background:rgba(255,255,255,.22);color:var(--cream);font-size:13px;font-weight:700;line-height:1;cursor:pointer;padding:0}
.vs-cnt button:hover{background:rgba(255,255,255,.38)}
.vs-cnt span{min-width:19px;text-align:center;font-weight:700;font-size:12px}
/* ============================================================
   VIDEO TYPE COLOURS  ·  NO TEAL
   Ona: "I don't want the chip to have any form of teal, period." The app is
   teal end to end and these badges were adding to it rather than cutting
   through it.
   Eight warm shades, every one a lightness or saturation move on brand coral,
   gold or yellow. Nothing from a new hue family, nothing teal. Chosen by
   measuring rather than by eye: the set was searched for maximum perceptual
   separation, with the three Ona asked to carry cream text constrained to
   fills dark enough to do it.
     minimum pairwise dE 20.6   (>20 reads as clearly different at badge size)
     worst text contrast 6.09:1 (every badge clears AA, none is borderline)
   Talking Head, Testimonial and Ad / Paid Social carry cream as asked. The
   rest take black, which is the stronger read on a light fill.
   Same class drives the card badge and the selected chip, so the modal and the
   dashboard agree.
   ============================================================ */
.bdg.vt-podcast,    .vs-chip.on.vt-podcast    {background:#E4C700; border-color:#E4C700; color:#000}          /* brand yellow  */
.bdg.vt-talking,    .vs-chip.on.vt-talking    {background:#5F5200; border-color:#5F5200; color:var(--cream)}  /* deep olive    */
.bdg.vt-testimonial,.vs-chip.on.vt-testimonial{background:#8F3A18; border-color:#8F3A18; color:var(--cream)}  /* terracotta    */
.bdg.vt-ad,         .vs-chip.on.vt-ad         {background:#5E2A12; border-color:#5E2A12; color:var(--cream)}  /* deep umber    */
.bdg.vt-event,      .vs-chip.on.vt-event      {background:#FFE873; border-color:#FFE873; color:#000}          /* pale yellow   */
.bdg.vt-tour,       .vs-chip.on.vt-tour       {background:#F0B968; border-color:#F0B968; color:#000}          /* light gold    */
.bdg.vt-explainer,  .vs-chip.on.vt-explainer  {background:#E87D49; border-color:#E87D49; color:#000}          /* brand coral   */
.bdg.vt-sizzle,     .vs-chip.on.vt-sizzle     {background:#9E8A00; border-color:#9E8A00; color:#000}          /* olive gold    */
.vs-err{font-size:11px;color:var(--coral);font-weight:600;padding:0 11px 9px;display:none}
.vs-sec.vs-bad .vs-err{display:block}
.vs-empty{font-size:11.5px;color:rgba(0,0,0,.35);font-style:italic;padding:2px 0}


/* ============================================================
   MY WEEK · personal weekly priorities (js/page-myweek.js)
   Appended, never merged into the rules above. Almost everything on the page
   reuses .card, .tbl, .btn, .sc, .bdg and .es; this is only what those did not
   already cover. No green: Done is dark teal.
   ============================================================ */
.mw-nav{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.mw-hint{font-size:11px;color:rgba(0,0,0,.4);margin-top:6px;line-height:1.5}
.mw-hint code{background:var(--cream);padding:1px 5px;border-radius:4px;font-size:10.5px}
.mw-tbl td{vertical-align:middle}
.mw-tbl .fi,.mw-tbl .fs{font-size:12px;padding:5px 8px}
/* Two classes, so these beat the single-class .fs background and the status
   colour actually shows on the dropdown. */
.mw-status.b-teal {background:rgba(11,58,57,.1); color:var(--teal);      border-color:rgba(11,58,57,.25)}
.mw-status.b-gold {background:rgba(208,148,47,.15);color:#8a6010;        border-color:rgba(208,148,47,.32)}
.mw-status.b-coral{background:rgba(232,125,73,.15);color:#b05a28;        border-color:rgba(232,125,73,.32)}
.mw-status.b-gray {background:rgba(0,0,0,.05);     color:rgba(0,0,0,.5)}
/* A finished item stays legible but stops competing for attention. */
.mw-tbl tr.mw-done td{opacity:.55}
.mw-ord{white-space:nowrap;padding-right:0}
.mw-arr{display:block;width:20px;height:15px;line-height:13px;padding:0;margin:0 auto;border:none;background:none;cursor:pointer;color:rgba(0,0,0,.35);font-size:9px}
.mw-arr:hover:not(:disabled){color:var(--teal)}
.mw-arr:disabled{opacity:.2;cursor:default}
.mw-add{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:10px 0 4px;border-top:1px solid rgba(0,0,0,.05);margin-top:6px}
@media(max-width:760px){
  .mw-add{flex-direction:column;align-items:stretch}
  .mw-add .btn{width:100%}
  .mw-nav .btn{flex:1;justify-content:center}
}
/* My Week: the item box is the widest thing in the row and should not be
   squeezed to nothing by the two dropdowns beside it. */
.mw-tbl .mw-item{width:100%;min-width:180px}

/* Settings menu in the top bar (Activity Log, Delivery Log, Team Management).
   Reuses the notification dropdown shell; these are just the rows inside it. */
.set-item{padding:10px 14px;font-size:12.5px;cursor:pointer;display:flex;align-items:center;gap:8px;border-bottom:1px solid rgba(0,0,0,.05)}
.set-item:last-child{border-bottom:none}
.set-item:hover{background:rgba(11,58,57,.05);color:var(--teal);font-weight:600}

/* Outreach: sortable column headers. */
.out-sortable{cursor:pointer;user-select:none}
.out-sortable:hover{color:var(--teal)}
.out-sortable::after{content:' \2195';opacity:.3;font-size:9px}

/* ============================================================
   CLICKABLE LINKS IN FORM FIELDS
   A URL in a text input cannot be clicked, so every asset, footage and
   submission link had to be copied out by hand. wireLinkOpeners() adds these
   from openM(). Sits under the field rather than beside it, so nothing in the
   existing two-column form grid has to move.
   ============================================================ */
.fld-open{
  display:inline-flex;align-items:center;gap:3px;margin-top:4px;
  font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;
  letter-spacing:.6px;text-transform:uppercase;color:var(--teal);
  text-decoration:none;border:1.5px solid rgba(11,58,57,.25);
  border-radius:5px;padding:2px 7px;background:rgba(11,58,57,.04);
  transition:background .12s,border-color .12s;
}
.fld-open:hover{background:var(--teal);border-color:var(--teal);color:var(--cream)}
.note-links{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin-top:6px}
.note-links-lbl{
  font-family:'Barlow Condensed',sans-serif;font-size:9px;font-weight:700;
  letter-spacing:1px;text-transform:uppercase;color:rgba(0,0,0,.35);margin-right:2px;
}
.note-links a{
  display:inline-flex;align-items:center;gap:3px;font-size:10.5px;
  color:var(--teal);text-decoration:none;border:1.5px solid rgba(11,58,57,.2);
  border-radius:20px;padding:2px 9px;background:rgba(11,58,57,.04);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.note-links a:hover{background:var(--teal);border-color:var(--teal);color:var(--cream)}

/* Performance Insights, appended 2026-08-18, per architectural rule 9.
   The two-up chart rows go single column on a phone; side by side they were
   160px wide and every bar label collided. */
@media(max-width:768px){
  .pi-grid{grid-template-columns:1fr!important}
}
/* Printing a report should give the report, not the app around it. */
@media print{
  #sidebar,#topbar,.mob-nav,.hamburger,#pi-controls,.tabs{display:none!important}
  #main{margin-left:0!important;padding-top:0!important}
  .card{break-inside:avoid;box-shadow:none;border:1px solid rgba(0,0,0,.12)}
}

/* Revenue Log cards, appended 2026-08-19, per architectural rule 9.
   Ona asked for the four cards to be told apart by colour. They are NOT given
   coral, gold and yellow: those three carry status meaning everywhere else in
   this system (at risk, needs attention, warning), so a revenue figure wearing
   coral would read as a problem rather than as a number. Four steps of the
   brand teal instead, darkest for the total, which distinguishes them without
   saying anything that is not true. Same reasoning as the expense donut. */
.sc.rev1{border-top-color:#83C3C0}
.sc.rev2{border-top-color:#4FA39F}
.sc.rev3{border-top-color:#2A817D}
.sc.rev4{border-top-color:#0B3A39}

/* CEO Dashboard, appended 2026-08-19, per architectural rule 9.
   The two grid rows collapse rather than squeezing four cards into a phone
   width, where the funnel and the gauge become unreadable. */
@media(max-width:1100px){
  .ceo-row2{grid-template-columns:1fr!important}
  .ceo-row3{grid-template-columns:1fr 1fr!important}
}
@media(max-width:768px){
  .ceo-row3{grid-template-columns:1fr!important}
}

/* HERO STAT ROW, appended 2026-08-19, per architectural rule 9.
   Started as a CEO-only class. Ona then asked for the same treatment on the Ops
   Dashboard, Due This Week, Revenue Overview, Revenue Log and Client MRR:
   "I want it to be, like, you can really see it. It catches your attention, so
   your eyes go directly to it versus you kinda miss it."
   So it is one class now rather than five copies of the same numbers.

   auto-fit, not a fixed four columns. Four tiles stretch to fill the row; a
   row of six wraps rather than shrinking every card to fit, which is the whole
   point of making them big. */
.srow.hero{grid-template-columns:repeat(auto-fit,minmax(230px,1fr))!important;gap:14px}
.srow.hero .sc{padding:20px 22px;border-top-width:5px}
.srow.hero .sl{font-size:10px;letter-spacing:2.2px;margin-bottom:6px}
.srow.hero .sv{font-size:40px}
.srow.hero .ss{font-size:11px;margin-top:6px}
@media(max-width:600px){.srow.hero{grid-template-columns:1fr!important}.srow.hero .sv{font-size:34px}}

/* RICH TEXT BODIES, appended 2026-08-19, per architectural rule 9.
   Ona: "if you look at the agenda and the bullet points and the numbering,
   everything is so close to the edge."
   Agenda and notes were rendered into a bare div, so the .md-body list rule
   further up never applied to them and the bullets sat against the edge of the
   card with the marker half outside it. This is that rule, plus the padding a
   list needs to have somewhere to put its marker. */
.rte-body ul,.rte-body ol{margin:6px 0 6px 0;padding-left:24px}
.rte-body li{margin-bottom:4px}
.rte-body p{margin:0 0 8px}
.rte-body p:last-child,.rte-body ul:last-child,.rte-body ol:last-child{margin-bottom:0}
.rte-body h1,.rte-body h2,.rte-body h3{font-family:'Barlow Condensed',sans-serif;margin:10px 0 6px;line-height:1.25}

/* ════════════════════════════════════════════════════════════
   ATRIUM CLIENT PORTAL, TAB SHELL. Added v8-120.
   Appended as a block and overwriting nothing above, per
   architectural rule 9.

   Colours here follow section 1b of the client side build brief,
   which is the chart and status scale, not the brand palette:
   #0B3A39 complete, #D8A400 in progress, #E4572E needs you,
   rgba(0,0,0,.25) not started. Note these are NOT --gold and
   --coral, which are the brand values and stay on buttons,
   layout and type. No green anywhere.
   ════════════════════════════════════════════════════════════ */

.cp-tabwrap{ position:sticky; top:0; z-index:5; background:var(--cream);
  border-bottom:1px solid rgba(0,0,0,.08); margin-bottom:14px; }

/* Horizontal pill row. Most clients open this on a phone from an email, so it
   scrolls sideways rather than wrapping, and the active tab is scrolled into
   view by the JS after every render. */
.cp-tabs{ display:flex; gap:6px; overflow-x:auto; padding:8px 2px;
  -webkit-overflow-scrolling:touch; scrollbar-width:none; }
.cp-tabs::-webkit-scrollbar{ display:none; }

.cp-tab{ flex:0 0 auto; display:inline-flex; align-items:center; gap:6px;
  font-family:'Barlow Condensed',sans-serif; font-size:13px; font-weight:700;
  letter-spacing:.03em; text-transform:uppercase;
  color:rgba(0,0,0,.55); background:transparent; border:1px solid transparent;
  border-radius:999px; padding:8px 14px; cursor:pointer; white-space:nowrap;
  min-height:44px; }
.cp-tab:hover{ background:rgba(11,58,57,.06); color:var(--teal); }
.cp-tab[aria-selected="true"]{ background:var(--teal); color:#fff; }

/* A number only appears when something is genuinely waiting on the client. A
   clean portal shows a clean tab bar. */
.cp-tab-badge{ display:inline-block; min-width:18px; padding:0 5px; border-radius:999px;
  background:#E4572E; color:#fff; font-size:11px; line-height:18px; text-align:center; }
.cp-tab[aria-selected="true"] .cp-tab-badge{ background:#fff; color:#E4572E; }

/* ---------- the phase bar ---------- */
/* Deliberately flex divs and not inline SVG, which is what the brief asks for
   elsewhere and is right for charts. Six stage names cannot reflow inside an
   SVG on a 375px screen without either clipping or shrinking to unreadable, and
   this is the one element every client looks at first. The bar itself carries
   the colour; the labels are ordinary text underneath and wrap normally. */
.cp-phase{ display:flex; gap:3px; margin:10px 0 6px; }
.cp-phase-seg{ flex:1; height:8px; border-radius:2px; background:rgba(0,0,0,.25); }
.cp-phase-seg.done{ background:#0B3A39; }
.cp-phase-seg.now{ background:#D8A400; }
.cp-phase-labels{ display:flex; gap:3px; }
.cp-phase-labels span{ flex:1; font-size:9px; line-height:1.15; text-align:center;
  color:rgba(0,0,0,.4); word-break:break-word; }
.cp-phase-labels span.now{ color:#D8A400; font-weight:800; }
.cp-phase-labels span.done{ color:#0B3A39; }

/* ---------- the weekly update ---------- */
.cp-update{ border-left:3px solid var(--teal); padding:2px 0 2px 12px; margin-bottom:14px; }
.cp-update h4{ font-family:'Barlow Condensed',sans-serif; font-size:15px; font-weight:800;
  color:var(--teal); margin:0 0 4px; }
.cp-update .cp-week{ font-size:10px; text-transform:uppercase; letter-spacing:.05em;
  color:rgba(0,0,0,.35); }
.cp-update p{ margin:6px 0 0; font-size:13px; line-height:1.55; }
.cp-update .cp-lbl{ font-family:'Barlow Condensed',sans-serif; font-size:11px; font-weight:800;
  text-transform:uppercase; letter-spacing:.05em; color:rgba(0,0,0,.45);
  display:block; margin-top:10px; }
.cp-update.cp-steady{ border-left-color:rgba(0,0,0,.25); }
.cp-blockers{ border-left:3px solid #E4572E; padding-left:12px; margin-top:10px; }
.cp-blockers .cp-lbl{ color:#E4572E; }

.cp-sec-t{ font-family:'Barlow Condensed',sans-serif; font-size:12px; font-weight:800;
  text-transform:uppercase; letter-spacing:.05em; color:rgba(0,0,0,.45); margin:0 0 8px; }

@media (max-width:640px){
  .cp-tab{ font-size:12px; padding:8px 12px; }
  .cp-phase-labels span{ font-size:8px; }
}

/* ── Atrium portal, Home layout and Updates controls. Added v8-124.
   Appended, overwriting nothing above, per architectural rule 9. ── */

/* Reference lives in a panel that is always in the same place. News lives in
   the main column. On a phone there is only one column and the news wins, so
   the panel drops underneath rather than above. */
.cp-2col{ display:grid; grid-template-columns:minmax(0,2fr) minmax(240px,1fr); gap:14px; align-items:start; }
.cp-side{ position:sticky; top:64px; }

.cp-upd-bar{ display:flex; gap:8px; margin-bottom:12px; flex-wrap:wrap; }
.cp-upd-bar .fi{ flex:1; min-width:160px; }
.cp-upd-bar select.fi{ flex:0 0 auto; width:auto; min-width:150px; }

@media (max-width:900px){
  .cp-2col{ grid-template-columns:1fr; }
  .cp-side{ position:static; }
}

/* -- Atrium client bell. Added v8-129. Appended, overwriting nothing. -- */
.cp-bell-wrap{ position:relative; display:inline-block; }
.cp-bell{ background:transparent; border:0; cursor:pointer; color:var(--cream);
  font-size:19px; line-height:1; padding:8px 10px; position:relative; min-height:44px; }
.cp-bell-dot{ position:absolute; top:2px; right:2px; background:#E4572E; color:#fff;
  font-family:'Barlow Condensed',sans-serif; font-size:10px; font-weight:800;
  min-width:16px; height:16px; line-height:16px; border-radius:999px; padding:0 4px; }
.cp-bell-panel{ position:absolute; right:0; top:100%; z-index:40; width:320px; max-width:88vw;
  background:#fff; border-radius:10px; box-shadow:0 10px 34px rgba(0,0,0,.22); overflow:hidden; }
.cp-bell-hd{ display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:10px 12px; border-bottom:1px solid rgba(0,0,0,.08);
  font-family:'Barlow Condensed',sans-serif; font-size:12px; font-weight:800;
  text-transform:uppercase; letter-spacing:.05em; color:rgba(0,0,0,.5); }
.cp-bell-list{ max-height:330px; overflow-y:auto; }
.cp-notif{ padding:10px 12px; border-bottom:1px solid rgba(0,0,0,.06); cursor:pointer; }
.cp-notif:hover{ background:rgba(11,58,57,.05); }
.cp-notif.unread{ border-left:3px solid #E4572E; }
.cp-notif-t{ font-size:13px; font-weight:700; color:var(--teal); }
.cp-notif-m{ font-size:12px; color:rgba(0,0,0,.6); margin-top:2px; line-height:1.4; }
.cp-notif-d{ font-size:10px; color:rgba(0,0,0,.35); margin-top:4px; }

/* -- Atrium client decisions. Added v8-131. Appended, overwriting nothing. -- */
.cp-decide{ display:flex; gap:4px; flex-wrap:wrap; }
.cp-decided{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; }
.cp-decided-d{ font-size:10px; color:rgba(0,0,0,.4); }

/* -- Atrium client feedback thread. Added v8-132. Appended, overwriting nothing. -- */
.cp-fb{ background:rgba(0,0,0,.03); border-radius:6px; padding:6px 9px; margin-top:6px; font-size:12px; }
.cp-fb-w{ font-family:'Barlow Condensed',sans-serif; font-size:11px; font-weight:800;
  text-transform:uppercase; letter-spacing:.04em; color:rgba(0,0,0,.45); margin-bottom:2px;
  display:flex; gap:6px; align-items:baseline; }

/* -- Atrium: needs your attention, and reminder checklists. v8-140. Appended. -- */
.cp-act{ display:flex; gap:10px; align-items:flex-start; padding:10px 0;
  border-bottom:1px solid rgba(0,0,0,.06); }
.cp-act:last-child{ border-bottom:0; }
.cp-act.blocking{ border-left:3px solid #E4572E; padding-left:10px; margin-left:-13px; }
.cp-act-t{ font-size:14px; font-weight:700; color:var(--teal); }
.cp-act-d{ font-size:12px; color:rgba(0,0,0,.6); line-height:1.5; margin-top:2px; }
.cp-act-m{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; font-size:11px; margin-top:5px; }
.cp-tick{ display:flex; gap:8px; align-items:flex-start; font-size:13px; padding:3px 0; cursor:pointer; }
.cp-tick input{ margin-top:3px; width:15px; height:15px; accent-color:var(--teal); flex-shrink:0; }
.cp-tick span.done{ text-decoration:line-through; color:rgba(0,0,0,.4); }

/* -- Atrium: past requests, a list you open. v8-146. Appended. -- */
.cp-row{ border-bottom:1px solid rgba(0,0,0,.07); }
.cp-row:last-child{ border-bottom:0; }
.cp-row-hd{ display:flex; align-items:center; gap:10px; padding:11px 14px; cursor:pointer; }
.cp-row-hd:hover{ background:rgba(11,58,57,.04); }
.cp-row.open .cp-row-hd{ background:rgba(11,58,57,.05); }
.cp-row-d{ font-size:11px; color:rgba(0,0,0,.4); flex:0 0 auto; min-width:92px; }
.cp-row-t{ flex:1; min-width:0; font-size:14px; font-weight:600; color:var(--teal);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cp-row-r{ color:#0B3A39; font-size:10px; }
.cp-row-x{ color:rgba(0,0,0,.3); font-size:15px; flex:0 0 auto; }
.cp-row-bd{ padding:2px 14px 14px; font-size:13px; line-height:1.55; }
.cp-row-bd p{ margin:0 0 6px; }
.cp-row-m{ font-family:'Barlow Condensed',sans-serif; font-size:11px; font-weight:800;
  text-transform:uppercase; letter-spacing:.05em; color:rgba(0,0,0,.4); margin-bottom:4px; }
@media (max-width:640px){
  .cp-row-hd{ flex-wrap:wrap; gap:6px; }
  .cp-row-d{ min-width:0; }
  .cp-row-t{ flex:1 0 100%; white-space:normal; }
}

/* ════════════════════════════════════════════════════════════════════
   COMMENT BOXES. Ona, 2026-08-26: "when leaving a comment on an
   assignment, I need more space. Right now it is a very tight little
   small box."

   They were <input> elements, one line at 11px, which is why. They are
   textareas now. handleCmtKey already treated Enter as send and shift
   and Enter as a newline, which only ever made sense for a textarea, so
   the handler was written for this and the markup had not caught up.

   Appended, not edited into .cin-row above, per architectural rule 9.
   ════════════════════════════════════════════════════════════════════ */
.cin-row{ align-items:flex-end; }
.cin-row textarea{
  flex:1; border:1.5px solid rgba(0,0,0,.1); border-radius:6px;
  padding:7px 9px; font-size:12px; line-height:1.5; outline:none;
  background:#fff; font-family:'Barlow',sans-serif;
  resize:vertical; min-height:62px; max-height:220px;
}
.cin-row textarea:focus{ border-color:var(--teal); }

/* ════════════════════════════════════════════════════════════════════
   COMPLETED VIDEO JOBS, AS A LIST

   Ona, 2026-08-26: "the completed section... almost squares to look like
   a spreadsheet. Right now it all being squares as well is gonna become
   overwhelming."

   Active and Ready for Review stay cards. Those are things somebody is
   about to act on, and the detail earns its space. Completed only ever
   grows, and nobody reads a finished job unless they are looking for one.

   Appended, not edited into the rules above, per architectural rule 9.
   ════════════════════════════════════════════════════════════════════ */
.vdone{ overflow:hidden; }
.vdone-hd,
.vdone-r{
  display:grid;
  grid-template-columns:minmax(0,2.2fr) minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr) 92px 22px;
  gap:10px; align-items:center; text-align:left;
}
.vdone-hd{
  padding:9px 14px; border-bottom:2px solid rgba(0,0,0,.06);
  font-family:'Barlow Condensed',sans-serif; font-size:9px; font-weight:700;
  letter-spacing:1.5px; text-transform:uppercase; color:rgba(0,0,0,.55);
}
.vdone-row{ border-bottom:1px solid rgba(0,0,0,.05); }
.vdone-row:last-child{ border-bottom:none; }
.vdone-r{
  width:100%; padding:10px 14px; background:none; border:0; cursor:pointer;
  font:inherit; color:inherit; transition:background .13s;
}
.vdone-r:hover{ background:rgba(11,58,57,.04); }
.vdone-c{ font-size:12px; color:rgba(0,0,0,.65); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.vdone-name{ font-family:'Barlow Condensed',sans-serif; font-size:14px;
  font-weight:800; color:var(--teal); }
.vdone-x{ font-size:15px; color:rgba(0,0,0,.3); transition:transform .13s;
  display:inline-block; }
.vdone-row[data-open="true"] .vdone-x{ transform:rotate(90deg); }
.vdone-row[data-open="true"] .vdone-r{ background:rgba(11,58,57,.04); }
.vdone-bd{ display:none; padding:4px 14px 14px 14px; background:rgba(11,58,57,.02); }
.vdone-row[data-open="true"] .vdone-bd{ display:block; }
.vdone-act{ display:flex; gap:6px; margin-top:10px; flex-wrap:wrap; }

/* Below 900px the five columns cannot hold. The job name and the chevron
   stay on one line and everything else stacks under it, which is still a
   list rather than a grid of squares. */
@media (max-width:900px){
  .vdone-hd{ display:none; }
  .vdone-r{ grid-template-columns:minmax(0,1fr) 22px; row-gap:4px; }
  .vdone-name{ grid-column:1; }
  .vdone-x{ grid-column:2; grid-row:1; }
  .vdone-c:not(.vdone-name){ grid-column:1; white-space:normal; }
}

/* ════════════════════════════════════════════════════════════════════
   MARKDOWN, AS TYPESET RATHER THAN AS EMITTED

   Ona, 2026-08-26: "I don't like the way the hyperlinks show. I don't
   like how the bold, italics, bullets. It is just not giving a full app
   integration system. It feels very, like, self built."

   The renderer was not the problem. The typography was, and one thing
   accounted for most of it: index.html loaded Barlow at 300 to 600 and
   no italic at all, so every <strong> was a browser synthesised faux
   bold and every <em> a slanted upright. Both look smeared next to a
   real cut, and that is the tell people read as homemade without being
   able to name it. index.html now loads 700 and the italics.

   The rest is spacing and affordance. Appended per rule 9; the rules at
   line 479 are left exactly as they are and these follow them.
   ════════════════════════════════════════════════════════════════════ */

/* Now that a real 700 exists, ask for it explicitly rather than letting
   the browser invent one. */
.md-body strong,
.md-body b{ font-weight:700; }
.md-body em,
.md-body i{ font-style:italic; }

/* Paragraphs were 2px apart, which reads as one block of text with
   accidental line breaks rather than as separate thoughts. */
.md-body div{ margin-bottom:6px; }
.md-body div:last-child{ margin-bottom:0; }
.md-body .md-sp{ height:9px; }

/* Lists: room to breathe, and a marker that is not competing with the
   text for weight. */
.md-body ul,
.md-body ol{ margin:7px 0 7px 20px; padding:0; }
.md-body li{ margin-bottom:5px; padding-left:2px; }
.md-body li:last-child{ margin-bottom:0; }
.md-body ul li::marker{ color:rgba(11,58,57,.45); }
.md-body ol li::marker{ color:rgba(11,58,57,.55); font-weight:600; }
.md-body ul ul,
.md-body ol ol,
.md-body ul ol,
.md-body ol ul{ margin-top:5px; margin-bottom:0; }

/* A link that looks like a link without shouting. The underline sits off
   the baseline so descenders are not struck through, which is most of
   what made the old one look like default browser output. */
.md-body a{
  color:var(--teal);
  text-decoration:underline;
  text-decoration-color:rgba(11,58,57,.35);
  text-decoration-thickness:1px;
  text-underline-offset:2px;
  font-weight:500;
  transition:color .13s, text-decoration-color .13s;
}
.md-body a:hover{ color:var(--coral); text-decoration-color:var(--coral); }

.md-body code{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  background:rgba(11,58,57,.06); color:var(--teal);
  padding:1px 5px; border-radius:4px; font-size:.92em;
}

/* @mention already had a colour elsewhere; this only stops it wrapping
   mid-name, which looked like two mentions. */
.md-body .mention{ white-space:nowrap; font-weight:600; }

/* ── Login screen: the Atrium mark alone. Ona, 2026-08-27 ──────────────────
   Appended, not edited into .login-logo-img, so the original rule is untouched
   and this only overrides what it needs to.
   The old logo was stacked and roughly square, so 60px tall was about 70px
   wide. The Atrium wordmark is 3:1, and 60px tall would run 180px across a
   320px card. Sized by height, so the ratio looks after itself.
   The larger bottom margin stands in for the "Atrium" line that used to sit
   under the logo and provided the gap before the email field. */
.login-logo-atrium{height:46px;margin-bottom:26px}


/* ══════════════════════════════════════════════════════════════════════════
   DESIGN TOKENS. Step 1 of the internal refinement. Ona, 2026-08-27.

   THIS BLOCK CHANGES NOTHING ON SCREEN. It only defines names. Not one
   existing token is redefined and not one existing rule is touched, so
   every page renders byte-identically to v8-218. The point is to have
   somewhere for the next steps to read from, and to make it impossible
   for the step after that to invent a fourteenth corner radius.

   WHY IT IS APPENDED RATHER THAN ADDED TO THE :root ON LINE 1.
   Working rule 9: CSS is appended as blocks, never overwritten. Line 1
   carries the whole app. A second :root is valid CSS, adds no conflict
   because nothing here is redeclared, and cannot damage what is above it.

   WHAT WAS MEASURED, AND WHY THESE NUMBERS.
   app.css currently holds 12 distinct greys for text, 14 corner radii,
   12 shadows and 12 line heights, none of them from a scale. css/atrium.css
   (the client portal) holds 3, 3, 1 and 2. The portal is the reference
   because it is the thing that already reads as finished. These tokens are
   the portal's system, restated for the CRM. Nothing here is invented.
   ══════════════════════════════════════════════════════════════════════════ */
:root{

  /* ── INK. Three tiers, replacing twelve ad hoc greys.
        Teal rather than #000 because pure black on cream is the harshest
        pairing available, and teal is a brand value rather than a default. */
  --ink:#0B3A39;
  --ink-muted:rgba(11,58,57,.70);
  --ink-subtle:rgba(11,58,57,.54);

  /* ── RULES AND QUIET FILLS. */
  --hairline:rgba(11,58,57,.12);
  --hairline-soft:rgba(11,58,57,.07);
  --surface-alt:rgba(11,58,57,.04);

  /* ── CORAL AND GOLD AS TEXT.
        The full brand values fail as type: #E87D49 on white measures 2.82:1
        and #D0942F on white 2.64:1, against the 4.5:1 needed. Both are taken
        down against black, which holds the hue and stays inside the brand.
          --coral-ink #904E2D  6.34:1 on white
          --gold-ink  #89621F  5.48:1 on white
        Full coral and gold stay on fills, rails, borders and large shapes,
        where 3:1 is the bar instead. Same derivation as the portal. */
  --coral-ink:#904E2D;
  --gold-ink:#89621F;

  /* ── SHAPE. Three radii, replacing fourteen. One shadow, replacing twelve.
        --shadow is deliberately far softer than the existing --sh: it is
        meant to sit under a hairline border, not to do the work alone. */
  --r-card:12px;
  --r-ctl:8px;
  --r-pill:999px;
  --shadow:0 1px 2px rgba(11,58,57,.06);

  /* ── TYPE SCALE. Seven roles, and a 13px floor.
        Barlow Condensed survives in exactly two of them, both at display
        size, where a narrowed face is an asset. Everywhere else it is
        Barlow, because Condensed at 9 to 12px, bold, uppercase and tracked
        is the single biggest reason the staff side is hard to read. */
  --fs-title:26px;   /* page title, Condensed 700 */
  --fs-stat:34px;    /* stat figure, Condensed 700, tabular */
  --fs-card:17px;    /* card heading, Barlow 600 */
  --fs-sec:15px;     /* section and card title, Barlow 600 */
  --fs-body:14px;    /* content */
  --fs-label:13px;   /* labels, meta, secondary. The floor. */
  --fs-badge:12px;   /* badge only, Condensed 600, the one small exception */

  /* ── WEIGHT. 84% of app.css is currently 700 or 800. When everything is
        bold nothing is emphasised, so 600 becomes the heaviest normal step. */
  --fw-body:400;
  --fw-med:500;
  --fw-semi:600;

  /* ── RHYTHM. Two, replacing twelve. */
  --lh-body:1.5;
  --lh-tight:1.3;
}


/* ══════════════════════════════════════════════════════════════════════════
   STEP 2: THE SHARED COMPONENTS READ FROM THE SCALE. Ona, 2026-08-27.

   Appended as overrides, per working rule 9. Not one original rule is
   edited. Reverting this is deleting the block, and nothing else.

   WHY IT IS WRAPPED IN @media(min-width:769px), WHICH MATTERS A LOT.
   app.css carries mobile rules from line 237 down that set font-size on
   .tbl, .btn-xs, .sv, .tab, .sh .btn and .tb-r .btn. A media query adds
   NO specificity, so an unconditional rule appended at the end of the file
   beats all of them and would have silently rewritten the phone layout
   while I was looking at a desktop screen. That is the same shape as the
   CSS line that removed three groups from the sidebar: correct where it
   was aimed, wrong somewhere nobody was looking.
   So desktop only for now. Every max-width rule still wins on mobile,
   untouched. Mobile is its own slice, done and checked separately.

   WHAT THIS CHANGES: type and colour only. No padding, no margin, no
   width, no radius, no shadow. Text does reflow when its size changes,
   and buttons and rows grow a little as a result, but no box model value
   is set here. Surfaces are the next slice.
   ══════════════════════════════════════════════════════════════════════════ */
@media(min-width:769px){

  /* ── Ink. Teal rather than #000, which is the harshest pairing on cream. */
  body{color:var(--ink)}

  /* ── Titles. Condensed 800 uppercase gives way to Barlow 600 sentence case. */
  .st{font-family:'Barlow',sans-serif;font-size:var(--fs-card);font-weight:var(--fw-semi);letter-spacing:normal;color:var(--ink)}
  .ct{font-family:'Barlow',sans-serif;font-size:var(--fs-sec);font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink)}
  .mt{font-family:'Barlow',sans-serif;font-size:var(--fs-card);font-weight:var(--fw-semi);letter-spacing:normal;color:var(--ink)}

  /* ── Tables. A 9px uppercase header was working harder than its own data. */
  .tbl th{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
  .tbl td{font-size:var(--fs-body);color:var(--ink)}

  /* ── Buttons and tabs. */
  .btn{font-family:'Barlow',sans-serif;font-size:var(--fs-body);font-weight:var(--fw-semi);letter-spacing:normal}
  .btn-g{color:var(--ink-muted)}
  .tab{font-family:'Barlow',sans-serif;font-size:var(--fs-body);font-weight:var(--fw-med);letter-spacing:normal;color:var(--ink-subtle)}
  .tab.active{font-weight:var(--fw-semi);color:var(--ink)}

  /* ── Badges. The one place Condensed stays small, because a badge is a
        badge: short, upper case, and read as a shape rather than a word. */
  .bdg{font-size:var(--fs-badge);font-weight:var(--fw-semi);letter-spacing:.06em}
  .b-coral{color:var(--coral-ink)}
  .b-gold{color:var(--gold-ink)}

  /* ── Stat cards. The figure keeps Condensed, which is what it is for. */
  .sl{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-med);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
  .sv{font-size:var(--fs-stat);font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
  .ss{font-size:var(--fs-label);color:var(--ink-subtle)}

  /* ── Forms. background-color, NOT the background shorthand: .fs carries the
        chevron as a background-image and the shorthand would erase it. */
  .fl{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink)}
  .fi,.fs,.fta{font-size:15px;color:var(--ink);background-color:var(--white)}

  /* ── Video and episode cards. This is the case Ona raised: the label was
        heavier than the thing it labelled, so the content lost. */
  .vid-client-name{font-family:'Barlow',sans-serif;font-size:var(--fs-card);font-weight:var(--fw-semi);line-height:var(--lh-tight)}
  .vid-row{font-size:var(--fs-body)}
  .vid-lbl{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-med);color:var(--ink-subtle)}
  .vid-val{color:var(--ink)}

  /* ── Task rows and pipeline cards. */
  .task-item-name{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--ink)}
  .task-item-meta{font-size:var(--fs-label);color:var(--ink-muted)}
  .dn{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--ink)}
  .dm{font-size:var(--fs-label);color:var(--ink-subtle)}
  .dsec-t{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
}


/* ══════════════════════════════════════════════════════════════════════════
   STEP 2b: THE SAME SCALE ON MOBILE. Ona, 2026-08-27.

   Appended after the max-width blocks above, so it wins over them by source
   order at equal specificity. Same principle as 2a and the same revert:
   delete the block.

   WHAT THIS DELIBERATELY DOES NOT SET: font-size on .sv, .tab, .btn, .tbl td
   and .fi/.fs/.fta. Those sizes were tuned for the phone already, across four
   breakpoints (768, 400, 380 and 600 for the hero row), and .fi carries an
   iOS zoom guard at 16px!important. Re-stating them here would flatten that
   work and reintroduce the pinch-zoom bug on iPhone. So mobile keeps its own
   sizes and takes only the face, the weight, the case and the ink.

   The sizes that ARE raised here are the ones that were below the floor for
   reasons that had nothing to do with the phone: 9px table headers, 9px stat
   labels, 10px form labels, 10px card labels and 10px meta.
   ══════════════════════════════════════════════════════════════════════════ */
@media(max-width:768px){

  body{color:var(--ink)}

  .st{font-family:'Barlow',sans-serif;font-size:16px;font-weight:var(--fw-semi);letter-spacing:normal;color:var(--ink)}
  .ct{font-family:'Barlow',sans-serif;font-size:14px;font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink)}
  .mt{font-family:'Barlow',sans-serif;font-size:16px;font-weight:var(--fw-semi);letter-spacing:normal;color:var(--ink)}

  /* Header case and ink only. The 11px mobile body size stays. */
  .tbl th{font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
  .tbl td{color:var(--ink)}

  /* Face and weight only. Mobile min-height and padding stay. */
  .btn{font-family:'Barlow',sans-serif;font-weight:var(--fw-semi);letter-spacing:normal}
  .btn-g{color:var(--ink-muted)}
  .tab{font-family:'Barlow',sans-serif;font-weight:var(--fw-med);letter-spacing:normal;color:var(--ink-subtle)}
  .tab.active{font-weight:var(--fw-semi);color:var(--ink)}

  .bdg{font-size:11px;font-weight:var(--fw-semi);letter-spacing:.06em}
  .b-coral{color:var(--coral-ink)}
  .b-gold{color:var(--gold-ink)}

  /* .sv keeps its 22px/24px/34px responsive sizes. Weight and figures only. */
  .sl{font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-med);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
  .sv{font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
  .ss{font-size:12px;color:var(--ink-subtle)}

  /* .fi/.fs/.fta keep 16px!important. Ink and ground only. */
  .fl{font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink)}
  .fi,.fs,.fta{color:var(--ink);background-color:var(--white)}

  .vid-client-name{font-family:'Barlow',sans-serif;font-size:16px;font-weight:var(--fw-semi);line-height:var(--lh-tight)}
  .vid-row{font-size:13px}
  .vid-lbl{font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-med);color:var(--ink-subtle)}
  .vid-val{color:var(--ink)}

  .task-item-name{font-size:13px;font-weight:var(--fw-semi);color:var(--ink)}
  .task-item-meta{font-size:12px;color:var(--ink-muted)}
  .dn{font-size:13px;font-weight:var(--fw-semi);color:var(--ink)}
  .dm{font-size:12px;color:var(--ink-subtle)}
  .dsec-t{font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-semi);letter-spacing:normal;text-transform:none;color:var(--ink-muted)}
}


/* ══════════════════════════════════════════════════════════════════════════
   STEP 3: THE CLIENT LINE UNDER A VIDEO OR EPISODE TITLE. Ona, 2026-08-27.

   New class, so it overrides nothing. Pairs with the change in
   js/page-video.js where the card stopped leading with the client name and
   started leading with the name of the work.
   ══════════════════════════════════════════════════════════════════════════ */
.vid-sub{font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-body);color:var(--ink-muted);margin-top:2px;line-height:var(--lh-tight)}
@media(max-width:768px){ .vid-sub{font-size:12px} }


/* ══════════════════════════════════════════════════════════════════════════
   STEP 5: FOUR THINGS ONA FOUND. 2026-08-27.

   1. The Completed table was missed by step 2. .vdone-name, .vdone-c and
      .vdone-hd are that table's own classes and were not in the list of
      shared components, so the job titles stayed Condensed 800 at 14px and
      the header stayed 9px uppercase while the rest of the app moved on.

   2. .due-done. A finished job's date is a date, not a warning. dueState
      only knows whether a date has passed, so every completed job showed a
      coral overdue chip. Neutral ink, and it reads as a record.

   3. An empty <input type="date"> paints its own mm/dd/yyyy skeleton using
      the input's colour, which step 2 set to --ink. So an empty date read
      as filled-in teal data while every other empty field showed a grey
      placeholder. .is-empty is toggled by syncEmptyDates() and puts the
      skeleton back at placeholder weight. :focus wins, so it goes to full
      ink the moment you click into it.
   ══════════════════════════════════════════════════════════════════════════ */

.due-done{background:var(--surface-alt);color:var(--ink-muted)}

.fi[type="date"].is-empty:not(:focus){color:var(--ink-subtle)}

@media(min-width:769px){
  .vdone-hd{
    font-family:'Barlow',sans-serif;font-size:var(--fs-label);font-weight:var(--fw-semi);
    letter-spacing:normal;text-transform:none;color:var(--ink-muted);
    border-bottom:1px solid var(--hairline);
  }
  /* .vdone-c BEFORE .vdone-name, and the order is load bearing. The title
     element is class="vdone-c vdone-name", both selectors are (0,1,0), so
     whichever is written last wins. With .vdone-c last the title rendered
     muted at 14px, which is the opposite of the fix. app.css has them in
     this order at 903 and 905 for the same reason. */
  .vdone-c{font-size:var(--fs-body);color:var(--ink-muted)}
  .vdone-name{
    font-family:'Barlow',sans-serif;font-size:var(--fs-sec);font-weight:var(--fw-semi);
    color:var(--ink);
  }
  .vdone-x{color:var(--ink-subtle)}
}
@media(max-width:768px){
  .vdone-hd{
    font-family:'Barlow',sans-serif;font-size:12px;font-weight:var(--fw-semi);
    letter-spacing:normal;text-transform:none;color:var(--ink-muted);
  }
  .vdone-c{font-size:13px;color:var(--ink-muted)}
  .vdone-name{
    font-family:'Barlow',sans-serif;font-size:14px;font-weight:var(--fw-semi);color:var(--ink);
  }
  .vdone-x{color:var(--ink-subtle)}
}


/* ══════════════════════════════════════════════════════════════════════════
   STEP 6: THE COMMENT DELETE, AND RICH TEXT THAT MATCHES THE PORTAL.
   Ona, 2026-08-27.

   .cmt-del. This was 9px Condensed and my own sweep in v8-224 lifted it to
   14px Barlow, which put the word DELETE at the same size as the comment it
   sits above. It is a destructive action that should be findable, not loud.
   Back down to 12px, sentence case, and only reaching full coral on hover.

   RICH TEXT. Links and list markers are the two things Ona has now raised
   twice. css/atrium.css already solved both for the portal and the CRM never
   got them: a soft underline held away from the text instead of a hard rule
   through its descenders, and a marker in quiet ink instead of a heavy black
   dot competing with the words. These mirror the portal, at staff density.
   ══════════════════════════════════════════════════════════════════════════ */

.cmt-del{
  font-family:'Barlow',sans-serif;font-size:12px;font-weight:500;
  background:none;border:0;padding:0;margin-left:8px;cursor:pointer;
  color:var(--ink-subtle);text-decoration:underline;
  text-decoration-color:rgba(11,58,57,.25);text-underline-offset:2px;
}
.cmt-del:hover{color:var(--coral-ink);text-decoration-color:var(--coral-ink)}

/* Links: soft rule, held off the baseline, so a URL in a note reads as prose
   with a link in it rather than as struck-through text. */
.md-body a{
  color:var(--teal);text-decoration:underline;
  text-decoration-color:rgba(11,58,57,.35);
  text-decoration-thickness:1px;
  text-underline-offset:2px;
  font-weight:500;
}
.md-body a:hover{color:var(--coral-ink);text-decoration-color:var(--coral-ink)}

/* Markers stop competing with the text. */
.md-body ul li::marker{color:var(--ink-subtle)}
.md-body ol li::marker{color:var(--ink-muted);font-weight:600}

@media(min-width:769px){
  .md-body{font-size:var(--fs-body);line-height:var(--lh-body);color:inherit}
  .md-body strong,.md-body b{font-weight:var(--fw-semi);color:var(--ink)}
  /* Comments were 11px, under the floor and smaller than everything near them. */
  .ctx.md-body{font-size:var(--fs-label);line-height:var(--lh-body)}
  .md-body code{background:var(--surface-alt);color:var(--teal);font-size:.92em}
}
@media(max-width:768px){
  .md-body{font-size:13px;line-height:var(--lh-body);color:inherit}
  .md-body strong,.md-body b{font-weight:var(--fw-semi);color:var(--ink)}
  .ctx.md-body{font-size:13px;line-height:var(--lh-body)}
}


/* ══════════════════════════════════════════════════════════════════════════
   STEP 7: OUTFIT IN THE CHROME. Ona chose it from the four way mockup,
   2026-08-27.

   WHY THIS ONE BLOCK IS UNCONDITIONAL, WHEN STEPS 2 AND 2b WERE NOT.
   The breakpoint trap that shaped those two was about font-SIZE: app.css
   tunes sizes per breakpoint and an unconditional rule flattens that. It
   sets font-FAMILY in 26 places and every one of them names the same value
   at both breakpoints, so there is nothing per breakpoint to preserve here.
   One block, and both widths get the same face. Not one size is touched.

   WHERE THE LINE IS DRAWN.
     Outfit  chrome and titles. The things you navigate and click: nav, top
             bar, section and card and modal titles, buttons, tabs, card
             headings, and the stat figure with its label as one unit.
     Barlow  everything you read or fill in: body copy, notes, table data,
             form labels and fields, meta and timestamps.
   The rule is that Outfit is the app talking and Barlow is the work talking.

   BARLOW CONDENSED IS NOT GONE. It keeps the jobs a narrow face is actually
   good at: badges, due chips, avatar monograms and the SVG chart numerals.
   It stops being the voice of the whole interface, which is what made the
   staff side hard to read in the first place.

   THIS IS A BRAND RULE CHANGE. Section 2 of CLAUDE.md names three faces and
   the app now loads four. Recorded in the commit rather than patched into
   the doc, per the standing decision not to edit CLAUDE.md piecemeal.
   ══════════════════════════════════════════════════════════════════════════ */
:root{ --font-ui:'Outfit','Barlow','Helvetica Neue',Arial,sans-serif; }

/* ── sidebar ── */
.ni,
.sb-grp-hd,
.nb{ font-family:var(--font-ui); }
/* Group headers stay upper case, which is a real job for a nav label, but come
   off 10px/800 Condensed. Caps at that size and weight in a narrow face is the
   least readable thing in the sidebar. */
.sb-grp-hd{ letter-spacing:.12em; font-size:11px; font-weight:600; }
.ni{ letter-spacing:0; font-weight:500; }
.ni.active{ font-weight:600; }

/* ── top bar ── */
.tb-title,
.tb-user{ font-family:var(--font-ui); letter-spacing:0; }
.tb-title{ font-weight:600; }

/* ── titles ── */
.st,
.ct,
.mt{ font-family:var(--font-ui); letter-spacing:0; }

/* ── controls ── */
.btn,
.tab{ font-family:var(--font-ui); letter-spacing:0; }

/* ── card headings and the stat block ── */
.vid-client-name,
.vdone-name,
.task-item-name,
.dn,
.sl,
.sv{ font-family:var(--font-ui); }

/* ── login, so the first screen matches the mark on it ── */
.login-btn,
.login-lbl{ font-family:var(--font-ui); letter-spacing:0; }
.login-lbl{ text-transform:none; font-size:13px; font-weight:600; color:var(--ink); }
.login-btn{ font-weight:600; }


/* ══════════════════════════════════════════════════════════════════════════
   STEP 7b: KEEP OUTFIT OUT OF THE CLIENT PORTAL. Ona, 2026-08-27.

   WHAT WENT WRONG IN v8-229. The Outfit block is unconditional and selects on
   bare class names. css/atrium.css scopes its own classes (.a-btn, .cp-tab,
   .a-lbl) but has no rule for the CRM classes the portal also uses, so
   `.btn{font-family:var(--font-ui)}` at (0,1,0) beat plain inheritance from
   .atrium and reached the client. Measured on the live portal: 30 .btn,
   6 .ct, 2 .tab and 1 .st came out Outfit while everything around them stayed
   Barlow. A half changed portal, which is worse than either whole answer.

   THE FIX IS ONE LINE OF CASCADE, NOT A LIST. Every Outfit rule reads
   var(--font-ui). Custom properties inherit, so redefining that one token on
   the client surface puts everything inside it back to Barlow, including any
   selector added to the Outfit block later. Nothing to keep in step.

   THE CLIENT SURFACE IS: the .atrium shell, plus the only three modals a
   client can actually open, which are opened from js/page-portal.js.
   m-delivery, m-client-action, m-client-reminder and m-client-update are NOT
   here: those are staff composing a message to a client, so they are CRM
   chrome and follow the CRM.

   DECIDED, 2026-08-27. Ona was shown the portal in Barlow against the same
   portal in Outfit and chose Barlow: "the portal is fine as is". So this is
   not a staging post on the way to unifying the two, and this block is not a
   leftover to be tidied away. The staff CRM speaks Outfit, the client portal
   speaks Barlow, and that is the intended end state.

   DO NOT DELETE THIS BLOCK to make the two surfaces match. If that ever comes
   up again it is a decision for Ona, not a consistency cleanup.
   ══════════════════════════════════════════════════════════════════════════ */
.atrium,
#m-client-episode,
#m-cp-changes,
#m-cp-seat{
  --font-ui:'Barlow','Helvetica Neue',Arial,sans-serif;
}


/* ══════════════════════════════════════════════════════════════════════════
   THE PAGE STAYS ZOOMED IN AFTER YOU TAP A FIELD. Ona, 2026-08-27.

   Ona: "the crm isnt mobile responsive", with screenshots of the CEO
   dashboard, the video dashboard and the sidebar all running off both edges
   of the phone, chrome included.

   IT IS NOT A LAYOUT OVERFLOW. Measured before changing anything: every page
   in those screenshots was rendered at 320px and at 375px and nothing crossed
   the viewport. document.scrollWidth equalled clientWidth on the CEO
   dashboard, on the video dashboard and inside the video job modal. Reading
   the screenshots back the other way says the same thing: the mobile bottom
   nav is position:fixed and left:0;right:0, so it is exactly one viewport
   wide by definition, and in Ona's screenshot it is wider than the screen.
   Nothing in a stylesheet can do that. Only zoom can.

   WHAT ACTUALLY HAPPENS: iOS Safari zooms the page in when you focus a text
   field whose font-size is under 16px, and it does not zoom back out when you
   leave the field. Everything after that looks cut off, including position:
   fixed chrome, because the visual viewport is now smaller than the layout
   viewport and horizontal panning drags fixed elements out of view.

   The two zoom levels in the screenshots are the two field sizes:
   16/14 = 1.14 for the login PIN, 16/12 = 1.33 for the comment box.

   The rule this is finishing already exists further up:
     .fi,.fs,.fta{font-size:16px!important} /* prevents iOS zoom * /
   It only ever covered fields carrying those three classes. These are the
   four that do not, found by walking every input, select, textarea and
   contenteditable in the document and reading its computed size:

     .login-sel/.login-pin   14px   the first thing touched every session
     .cin-row textarea       12px   the three @mention comment boxes
     .cin-row input          11px   the older single line comment field
     .rte-field              12px   the rich text bodies, contenteditable
     .tbl td input[number]   12px   payment queue amount, inline style,
                                    which is why that one needs !important

   NOT maximum-scale=1 or user-scalable=no on the viewport tag. That stops the
   symptom by taking pinch zoom away from everybody, including anyone who
   needs it to read. 16px fields fix the cause and leave zoom alone.

   Phone only. On a desktop these sizes are deliberate and unchanged.
   ══════════════════════════════════════════════════════════════════════════ */
@media(max-width:768px){
  .login-sel,.login-pin{font-size:16px}
  .cin-row input,.cin-row textarea{font-size:16px}
  .rte-field{font-size:16px}
  .tbl td input[type="number"]{font-size:16px!important}
}

/* ══════════════════════════════════════════════════════════════════════════
   DATE AND TIME FIELDS READ AS BLACK, NOT TEAL. Ona, 2026-08-28.

   "why are dates this teal color". Nothing was colouring dates specifically.
   --ink is #0B3A39, the brand Dark Teal, and it is the app's text colour in
   place of black, so every label, cell and field value is already that colour.
   It only LOOKS teal in a date or time field, because the browser lays those
   digits out wide and evenly spaced on a pale ground, which surfaces the tint
   that ordinary prose hides.

   So the fix is not to correct a wrong colour, it is to stop these two field
   types showing the tint the rest of the app gets away with. Black is on the
   brand list and is the designated text colour, so that is what they use.

   Scope is deliberately these two input types and nothing else. Labels, text
   fields and body copy stay on --ink. That keeps them all READING the same,
   which is the point, even though the hex now differs.

   Appended rather than edited into the rules at the two .fi colour
   declarations above, per working rule 9. Both of those live inside media
   queries and are (0,1,0). These are (0,2,0) on an attribute selector, so they
   win in both breakpoints without a media query of their own and without
   touching the phone layout. Checked against the live stylesheet before it
   was written: filled goes to black, the text field beside it stays teal.

   The empty state keeps its faded placeholder, moved to black at 45% so a
   field does not change hue the moment a date is picked. :focus still wins,
   so clicking in goes to full strength.
   ══════════════════════════════════════════════════════════════════════════ */

.fi[type="date"],.fi[type="time"]{color:var(--black)}
.fi[type="date"].is-empty:not(:focus),
.fi[type="time"].is-empty:not(:focus){color:rgba(0,0,0,.45)}

/* ══════════════════════════════════════════════════════════════════════════
   OUTREACH: PRIORITY STAR AND CLICKABLE ROWS
   Added 2026-08-28. Appended, per the rule, so nothing above is overwritten.

   The whole outreach row opens the prospect, so it needs to look like it does.
   Links and the star inside the row stop the click bubbling in JS; the cursor
   here is set back to the pointer they already carry so the two never disagree
   about what a click will do.

   The star is gold, which in this system means "needs attention". Coral was
   wrong: coral is at risk or overdue, and a priority prospect is neither.
   ══════════════════════════════════════════════════════════════════════════ */

.out-row{cursor:pointer}
.out-row:hover{background:rgba(11,58,57,.045)}
.out-row a{cursor:pointer}

/* Narrow, so the star never pushes the business name off a phone. */
th.out-star-h{width:34px;text-align:center;color:var(--gold);opacity:.5}
td.out-star-c{width:34px;text-align:center;padding-left:4px;padding-right:4px}

.out-star{background:none;border:none;padding:2px 4px;line-height:1;cursor:pointer;
  font-size:17px;color:rgba(0,0,0,.22);transition:color .12s,transform .12s}
.out-star:hover{color:var(--gold);transform:scale(1.15)}
.out-star.on{color:var(--gold)}
.out-star:focus-visible{outline:2px solid var(--teal);outline-offset:2px;border-radius:4px}

/* ══════════════════════════════════════════════════════════════════════════
   ONE EDITOR
   2026-08-28. Styles for the contenteditable that replaced both the Markdown
   textarea and the older rte- boxes. See 02-shared.js, "ONE EDITOR", for why
   there were two of them.

   APPENDED, and the phone override is appended UNDER it on purpose. A media
   query adds no specificity, so the 16px rule in the @media block up at line
   ~278 would lose to anything set on .rt-field down here. The phone block at
   the bottom of this section is what keeps iOS from zooming the page when a
   box is tapped.
   ══════════════════════════════════════════════════════════════════════════ */

.rt-bar{display:flex;gap:3px;align-items:center;flex-wrap:wrap;margin-bottom:5px}
.rt-btn{border:1.5px solid rgba(0,0,0,.12);background:#fff;border-radius:5px;min-width:28px;height:26px;
  padding:0 7px;cursor:pointer;font-family:'Barlow Condensed',sans-serif;font-size:12px;font-weight:700;
  color:var(--teal);line-height:1;transition:background .12s,border-color .12s,color .12s}
.rt-btn:hover{background:var(--cream2);border-color:rgba(11,58,57,.3)}
/* The lit state is what says "you are typing in bold". The old toolbar had no
   way to show this, which is why unbolding felt impossible. */
.rt-btn.on{background:var(--teal);color:var(--cream);border-color:var(--teal)}
.rt-btn:focus-visible{outline:2px solid var(--teal);outline-offset:1px}
.rt-sep{width:1px;height:18px;background:rgba(0,0,0,.12);margin:0 4px}
.rt-bar-sm .rt-btn{height:23px;min-width:25px;padding:0 6px;font-size:11px}

.rt-field{border:1.5px solid rgba(0,0,0,.11);border-radius:7px;background:var(--cream);
  padding:9px 11px;font-family:'Barlow',sans-serif;font-size:13px;line-height:1.6;color:var(--black);
  /* Ona: "I hate that I have to scroll to be able to see it." The old box was
     min-height 60px, about three lines. */
  min-height:150px;max-height:60vh;overflow:auto;resize:vertical;outline:none;
  transition:border .13s;word-break:break-word}
.rt-field:focus{border-color:var(--teal)}
.rt-field.rt-sm{min-height:70px}
.rt-field:empty:before{content:attr(data-ph);color:rgba(0,0,0,.32);pointer-events:none}

/* Links look the same here as they do everywhere they are read back: .md-body
   in the CRM and .atrium .md-body in the portal. They were the one thing the
   old editor could not show at all, because it stored [text](url) as text. */
.rt-field a{color:var(--teal);text-decoration:underline;text-decoration-color:rgba(11,58,57,.35);
  text-underline-offset:2px;font-weight:500}
.rt-field a:hover{text-decoration-color:var(--teal)}
.rt-field strong,.rt-field b{font-weight:700}
.rt-field em,.rt-field i{font-style:italic}
.rt-field ul,.rt-field ol{margin:4px 0 4px 20px}
.rt-field li{margin-bottom:2px}
.rt-field code{background:rgba(0,0,0,.06);padding:1px 4px;border-radius:3px;font-size:12px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.rt-field p{margin:0 0 4px}

/* The link dialog. Replaces prompt(), which could not be styled, could not show
   the text being linked, and on a phone is a system alert over the whole app. */
.rt-link-row{margin-bottom:10px}
.rt-link-row label{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;
  letter-spacing:1px;text-transform:uppercase;color:rgba(0,0,0,.6);display:block;margin-bottom:4px}

@media(max-width:768px){
  /* 16px, or iOS zooms the page in on focus and leaves it there. Same reason as
     the .fi,.fs,.fta rule further up this file. */
  .rt-field{font-size:16px;min-height:180px}
  .rt-field.rt-sm{min-height:96px}
  .rt-btn{height:30px;min-width:32px}
}

/* The outcome choice on a client reply. Two radios that each say what they will
   do, because the thing they replaced was one checkbox whose unticked state
   silently did nothing. */
.rqr-opt{display:flex;gap:9px;align-items:flex-start;cursor:pointer;padding:9px 11px;margin-top:6px;
  border:1.5px solid rgba(0,0,0,.11);border-radius:8px;background:var(--cream);transition:border-color .13s,background .13s}
.rqr-opt:hover{border-color:rgba(11,58,57,.3)}
.rqr-opt:has(input:checked){border-color:var(--teal);background:#fff}
.rqr-opt input{width:15px;height:15px;accent-color:var(--teal);margin-top:2px;flex-shrink:0}
.rqr-opt b{display:block;font-size:12.5px;font-weight:600}
.rqr-opt em{display:block;font-style:normal;font-size:11px;color:rgba(0,0,0,.5);margin-top:2px;line-height:1.45}

/* A thread, wherever one is read inside the CRM. The portal has its own .a-note
   and is deliberately not touched by this. */
.cd-thread{border-left:2px solid rgba(11,58,57,.16);padding-left:11px;margin:0 0 13px}
.cd-note{padding:8px 0;border-bottom:1px solid rgba(0,0,0,.055)}
.cd-note:last-child{border-bottom:none}
.cd-note-w{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin-bottom:3px}
.cd-note-w b{font-size:12px;font-weight:700}
.cd-note-w span{font-size:11px;color:rgba(0,0,0,.42)}
.cd-note-w .cd-who{font-family:'Barlow Condensed',sans-serif;font-size:9.5px;font-weight:700;letter-spacing:.8px;
  text-transform:uppercase;padding:1px 6px;border-radius:20px}
.cd-who-team{background:rgba(11,58,57,.11);color:var(--teal)}
.cd-who-client{background:rgba(232,125,73,.15);color:#b4551f}
.cd-thread-h{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;color:rgba(0,0,0,.42);margin-bottom:2px}

/* The link dialog opens ON TOP of the modal that owns the editor. Every .mov
   sits at z-index 500 and stacks in document order, so without this it would
   fall behind any modal declared after it in index.html. */
#m-rt-link{z-index:640}

/* A link in the editor opens on click, so it has to look like it will. Without
   this it is an underlined word with a text caret over it, which is what
   "I can't click on any of the links" looked like from the other side. */
.rt-field a{cursor:pointer}

/* ══════════════════════════════════════════════════════════════════════════
   PAST MEETINGS FOLD SHUT
   2026-08-28. A past meeting was a full card of agenda, notes, action items
   and attendees, so the Past tab was a page of scrolling to find one line.
   Modelled on the portal's own disclosure rows, which Ona pointed at.

   The HEADER never hides. Title, date and every status badge stay readable
   shut, because "is this in their portal, does it have client notes" is the
   question the list is there to answer.
   ══════════════════════════════════════════════════════════════════════════ */

/* nowrap on the HEADER, wrap inside the badge strip. .ch wraps by default, and
   with three children that dropped the chevron onto a line of its own under the
   badges at any middling width. The badges still wrap among themselves. */
.mt-fold > .ch{cursor:pointer;user-select:none;gap:10px;flex-wrap:nowrap;align-items:flex-start}
/* The TITLE takes the slack, the badges take what they need. The other way
   round and the badge strip claimed the free space and squeezed the date line
   onto two rows while empty space sat beside it. */
.mt-fold > .ch > :first-child{flex:1 1 auto;min-width:0}
.mt-fold > .ch > :nth-child(2){flex:0 1 auto;min-width:0}
.mt-fold > .ch:hover{background:rgba(11,58,57,.035)}
/* !important, and it has to be. The card body is written with an INLINE
   style="display:grid;grid-template-columns:..." so the agenda and the notes
   sit side by side, and an inline style beats any stylesheet rule that is not
   important. Without this the rule lost silently: data-open toggled, the
   chevron turned, and the body never moved.

   The first test of this used a bare <div class="cb"> with no inline style, so
   it passed while production did not. Test the markup the page actually emits. */
.mt-fold[data-open="false"] > .cb{display:none!important}
/* No bottom border under a shut header, or every closed row draws a line to
   nothing. */
.mt-fold[data-open="false"] > .ch{border-bottom:none}

.mt-chev{flex-shrink:0;align-self:center;width:9px;height:9px;margin-left:2px;
  border-right:2px solid rgba(11,58,57,.45);border-bottom:2px solid rgba(11,58,57,.45);
  transform:rotate(-45deg);transition:transform .16s}
.mt-fold[data-open="true"] .mt-chev{transform:rotate(45deg)}
.mt-fold > .ch:hover .mt-chev{border-color:var(--teal)}

/* ── v8-267 · the client's own words on a video job card ─────────────────────
   The thread renderer is shared with the Client Desk (cdThreadHtml), and its
   trailing margin is sized for a page, not for the inside of a coral box. The
   rule is scoped to .vid-cfb so the desk's own threads are untouched. */
.vid-cfb .cd-thread{margin:0;border-left-color:rgba(228,87,46,.32)}
.vid-cfb .cd-note:first-child{padding-top:2px}
.vid-cfb .cd-note:last-child{padding-bottom:0}

/* ── v8-269 · the same block, now inside the job rather than on the card ─────
   It sits above the first field in the modal, so it needs the gap underneath
   that a card used to give it above, and a little more room to breathe than a
   card could spare. */
#vj-client-fb .vid-cfb,#ep-client-fb .vid-cfb{margin:0 0 15px;padding:9px 12px}

/* ── v8-270 · four controls in a 280px card header ──────────────────────────
   Ona, 2026-08-29: "its cut off". A released job that needs revision carries
   NEEDS REVISION, RELEASED, Unrelease and Edit, and .vid-top was a nowrap flex
   row, so the last two ran off the right edge of the card and the title was
   squeezed to "What / I do" to make room for them.
   Not only the revision case. Completed plus "Release to client" plus Edit did
   the same to every job waiting to go out, which is why "The Bridge" beside it
   was a one word column.
   The header wraps now, the title keeps the full width, and the controls fall
   to their own line as one left aligned group. No row-gap declared here on
   purpose: that row carries an inline gap:5px, and an inline shorthand beats a
   stylesheet rule, so it would be a dead line. */
.vid-top{flex-wrap:wrap;gap:8px}
.vid-top>div:first-child{min-width:0;flex:1 1 150px}
.vid-top>div:last-child{flex-wrap:wrap;justify-content:flex-start}

/* ── v8-272 · the video card opens the job ──────────────────────────────────
   Ona, 2026-08-29: "I wanna be able to just click on the card for it to open."
   The card carries the onclick now, so it has to say so before it is clicked.
   The task cards on the same dashboard have been openable for months with no
   pointer at all, so this covers both. Hover is a lift, not a colour: these
   cards already carry status colour and a second one would compete with it. */
.vid-card-open,.vid-card[onclick]{cursor:pointer}
.vid-card-open:hover,.vid-card[onclick]:hover{box-shadow:0 3px 12px rgba(11,58,57,.16)}
/* Everything in the header is its own control. Release, Unrelease and Edit all
   stop the click in JS; this stops them inheriting the card's pointer too. */
.vid-card-open .vid-top .btn{cursor:pointer}

/* ── v8-272 · room to write a comment ───────────────────────────────────────
   The three comment boxes went back to textareas today, and the rich text box
   they replaced stood at 70px. Ona asked for the box to stay at least as big
   as it had become, so the textarea meets it rather than dropping to the 62px
   it had before. Appended per architectural rule 9. */
.cin-row textarea{min-height:76px}
@media(max-width:768px){ .cin-row textarea{min-height:96px} }

/* ── v8-274 · releasing work to a client, on one screen ─────────────────────
   Ona, 2026-08-29: "lets do the release flow."
   Three browser dialogs became one modal. The option cards are the same shape
   as the ones in the client request reply modal (.rqr-opt): repeated here
   rather than the class being reused under its old name, because a selector
   named for one modal doing the work of two is how a change to one of them
   quietly lands in the other. Noted in ISSUES.md as a pair worth merging under
   a shared name when a third one appears. */
.rel-ctx{background:var(--cream);border-radius:8px;padding:10px 12px;margin-bottom:14px;line-height:1.5}
.rel-ctx b{display:block;font-size:13px;font-weight:600;color:var(--ink)}
.rel-ctx span{display:block;font-size:11.5px;color:rgba(0,0,0,.5);margin-top:1px}
.rel-opt{display:flex;gap:9px;align-items:flex-start;cursor:pointer;padding:9px 11px;margin-top:6px;
  border:1.5px solid rgba(0,0,0,.11);border-radius:8px;background:var(--cream);transition:border-color .13s,background .13s}
.rel-opt:hover{border-color:rgba(11,58,57,.3)}
.rel-opt:has(input:checked){border-color:var(--teal);background:#fff}
.rel-opt input{width:15px;height:15px;accent-color:var(--teal);margin-top:2px;flex-shrink:0}
.rel-opt b{display:block;font-size:12.5px;font-weight:600}
.rel-opt em{display:block;font-style:normal;font-size:11px;color:rgba(0,0,0,.5);margin-top:2px;line-height:1.45}
/* What the client actually gets. This is the sentence the confirm() used to
   ask, said before the button instead of after it. */
.rel-says{margin-top:14px;padding-top:11px;border-top:1px solid rgba(0,0,0,.07);
  font-size:11.5px;line-height:1.5;color:var(--ink-muted)}

/* ══════════════════════════════════════════════════════════════════════════
   STATUS UPDATES GET THE EDITOR
   2026-08-31. Ona: the check-in box "needs to be bigger and needs to allow
   formatting such as bullet points, bolding and links". Both status update
   boxes are .rt-field now, so the size and the toolbar come from the ONE
   EDITOR block above and nothing is set twice. Two things it does not cover:
   ══════════════════════════════════════════════════════════════════════════ */

/* The Monday gate sits at z-index 10000, above every .mov in the app, so the
   link dialog opened behind it and the box looked like it had swallowed the
   click. Raised over the gate rather than lowering the gate, which is what
   keeps the CRM out of sight until the updates are written. */
#m-rt-link{z-index:10050}

/* The status log reads at the size it always did. .md-body is declared later
   in this file than .su-text and would otherwise win on equal specificity. */
.su-text.md-body{font-size:12px}

/* ── RECURRING TASKS: reminders, due dates and the login banner ─────────────
   Appended, never merged into the rules above, per the CSS rule in CLAUDE.md.
   Added 2026-09-06 with the reminder/review split.

   Brand colours only and no green: gold is "needs attention", coral is "late",
   teal is "settled". Same three meanings the rest of the system uses. */
.rec-kind{display:inline-block;font-family:'Barlow Condensed',sans-serif;font-size:9px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;padding:1px 6px;border-radius:4px;vertical-align:middle;margin-left:4px}
.rec-kind-rem{background:rgba(11,58,57,.10);color:#0B3A39}
.rec-kind-rev{background:rgba(208,148,47,.16);color:#8a6114}
.rec-due-line{margin-top:3px}
.rec-due,.rec-due-today,.rec-due-late,.rec-due-warn{font-family:'Barlow Condensed',sans-serif;font-size:11px;font-weight:600;letter-spacing:.2px}
.rec-due{color:var(--ink-subtle)}
.rec-due-today{color:#8a6114}
.rec-due-late{color:var(--coral)}
.rec-due-warn{color:var(--coral);font-weight:700}
/* Undo sits beside "Done" and has to be reachable without being a second
   call to action, so it reads as a link rather than a button. */
.rec-undo{font-family:'Barlow Condensed',sans-serif;font-size:10px;font-weight:600;color:var(--ink-subtle);text-decoration:underline;cursor:pointer;margin-left:6px}
.rec-undo:hover{color:var(--coral)}

/* The banner. Gold, because a reminder is "needs attention" and not "at risk":
   coral here would make every Tuesday look like an emergency and the colour
   would stop meaning anything on the days something has actually gone wrong. */
.rec-banner{background:#fdf6e6;border:1px solid rgba(208,148,47,.45);border-left:4px solid var(--gold);border-radius:8px;padding:11px 14px;margin-bottom:14px}
.rec-banner-ttl{font-family:'Barlow Condensed',sans-serif;font-size:13px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:#8a6114;margin-bottom:5px}
.rec-banner-list{margin:0 0 8px;padding-left:18px;font-family:'Barlow',sans-serif;font-size:13px;color:#000;line-height:1.55}
.rec-banner-list li{margin:0}
.rec-banner-more{font-family:'Barlow',sans-serif;font-size:12px;color:var(--ink-subtle);margin-bottom:8px}
@media(max-width:768px){
  .rec-banner{padding:10px 12px;margin-bottom:11px}
  .rec-banner-list{font-size:12.5px}
}
