  :root{
    /* One notification row's exact height, and the only number the "five at a
       time" rule depends on: #notifList's max-height is five of these. Changing
       the row's padding or font size moves the cutoff with it, instead of
       leaving a hardcoded pixel value that slowly stops meaning five. */
    /* 84 leaves the content (24 padding + 1 border + two clamped
       12.5px/1.45 lines + the timestamp ~= 77) room to sit centred with
       air above and below, rather than filling the row edge to edge.
       The list's max-height is five of these, so the panel's height
       follows from this one number. */
    --np-item-h:84px;
    --brand:#2161AC; --brand-hover:#1B528F; --brand-soft:#E8F0FA;
    --bg:#F5F6F8; --surface:#FFFFFF; --border:#E1E4E8;
    --text:#1F2328; --text-2:#57606A; --text-3:#8B949E;
    --success:#1A7F37; --success-soft:#E6F4EA; --warning:#9A6700; --danger:#CF222E;
    --danger-soft:#FDF2F3; --warning-soft:#FFF8E6;
    font-size:14px;
  }
  *{box-sizing:border-box;margin:0;padding:0}
  html,body{height:100%}
  body{font-family:"Segoe UI Variable","Segoe UI",Inter,system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);-webkit-font-smoothing:antialiased}
  button{font-family:inherit;cursor:pointer}
  a{color:var(--brand);text-decoration:none}
  .hidden{display:none!important}
  svg.ic{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
  svg.ic.sm{width:16px;height:16px}
  svg.ic.xs{width:14px;height:14px}
  svg.ic.fill-star{fill:#B8860B;stroke:#B8860B}

  /* Login */
  #loginView,#otpView{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(180deg,#EEF2F8 0%,#F5F6F8 100%);padding:24px}
  .login-logo{display:flex;align-items:center;justify-content:center;margin-bottom:28px}
  .app-logo-full{height:auto;display:block}
  .login-logo .app-logo-full{width:260px;max-width:80vw}
  .topbar-logo{width:auto;height:28px}
  .login-card{background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:0 8px 30px rgba(20,30,60,.07);width:100%;max-width:400px;padding:36px}
  .login-card h1{font-size:21px;font-weight:600;margin-bottom:4px}
  .login-card .sub{color:var(--text-2);margin-bottom:24px;font-size:13.5px}
  .field{margin-bottom:16px}
  .field label{display:block;font-size:12.5px;font-weight:600;color:var(--text-2);margin-bottom:6px}
  .field input,.field select,.field textarea{width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:6px;font-size:14px;font-family:inherit;background:#fff;color:var(--text)}
  .field textarea{resize:vertical;min-height:64px}
  .field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--brand);outline-offset:-1px;border-color:var(--brand)}
  .field .fhint{font-size:11.5px;color:var(--text-3);margin-top:5px;line-height:1.4}
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;border-radius:6px;padding:10px 18px;font-size:14px;font-weight:600}
  .btn-primary{background:var(--brand);color:#fff;width:100%}
  .btn-primary:hover:not(:disabled){background:var(--brand-hover)}
  /* A disabled button has to LOOK disabled. doForgotPassword() correctly sets
     btn.disabled and relabels it "Sent", but with no disabled styling it kept
     full brand colour and still lit up on hover, so the finished state read as
     a live button someone should press again. :not(:disabled) on the hover
     rules above is half of the fix - without it, hover still repainted the
     background over anything set here. */
  .btn:disabled,button:disabled{opacity:.55;cursor:default;box-shadow:none}
  .btn-sec:hover:not(:disabled){background:#F3F4F6}
  .btn-danger:hover:not(:disabled){background:#FDF2F3}
  .btn-sec{background:var(--surface);border:1px solid var(--border);color:var(--text);padding:7px 14px;font-weight:500;display:inline-flex;align-items:center;gap:7px}
  .btn-danger{background:#fff;border:1px solid #F0C4C8;color:var(--danger)}
  /* Phase 11 - the licence panel in Settings, and the same three states the
     operator portal uses so the two read alike. */
  .lic-state{font-size:13.5px;font-weight:600;border-radius:6px;padding:9px 12px;margin-bottom:14px;line-height:1.4}
  .lic-ok{background:var(--success-soft);color:var(--success)}
  .lic-soon{background:var(--warning-soft);color:var(--warning)}
  .lic-expired{background:var(--danger-soft);color:var(--danger)}
  .lic-rows{display:flex;flex-direction:column;gap:9px}
  .lic-rows > div{display:flex;justify-content:space-between;align-items:baseline;gap:16px;font-size:13.5px}
  .lic-rows span{color:var(--text-2)}
  .lic-rows b{font-weight:600;text-align:right}
  .login-foot{margin-top:22px;text-align:center;font-size:12.5px;color:var(--text-3)}
  .login-error{background:#FDF2F3;border:1px solid #F0C4C8;color:var(--danger);font-size:12.5px;border-radius:6px;padding:8px 12px;margin-bottom:14px;line-height:1.4}
  .forgot{font-size:12.5px}
  .otp-boxes{display:flex;gap:10px;justify-content:center;margin:26px 0}
  .otp-boxes input{width:46px;height:54px;text-align:center;font-size:22px;font-weight:600;border:1px solid var(--border);border-radius:8px}
  .otp-boxes input:focus{outline:2px solid var(--brand);border-color:var(--brand)}
  .trust{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-2);margin-bottom:18px;justify-content:center}

  /* Shell */
  #appShell{display:none;height:100vh;flex-direction:column}
  .topbar{height:60px;background:var(--surface);border-bottom:1px solid var(--border);display:grid;grid-template-columns:1fr minmax(280px,560px) 1fr;align-items:center;padding:0 20px;gap:16px;flex-shrink:0;z-index:30}
  .topbar .brand{display:flex;align-items:center;gap:11px;justify-self:start}
  .topbar .brand b{font-size:17px;font-weight:700}
  .topbar .brand b span{color:var(--brand)}
  .search-wrap{width:100%;justify-self:center;position:relative}
  .search-wrap input{width:100%;padding:8px 12px 8px 34px;border:1px solid var(--border);border-radius:6px;background:var(--bg);font-size:13.5px;font-family:inherit}
  .search-wrap input:focus{outline:2px solid var(--brand);background:#fff}
  .search-wrap .sicon{position:absolute;left:10px;top:9px;color:var(--text-3)}
  .search-results{position:absolute;top:40px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 10px 30px rgba(20,30,60,.12);padding:6px;display:none;max-height:340px;overflow:auto;z-index:50}
  .search-results.open{display:block}
  .sr-head{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--text-3);padding:8px 10px 4px}
  .sr-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer;font-size:13.5px}
  .sr-item:hover{background:var(--brand-soft)}
  .sr-item .type-ic{width:26px;height:26px;border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
  .topbar-right{justify-self:end;display:flex;align-items:center;gap:6px}
  .icon-btn{width:36px;height:36px;border-radius:8px;border:none;background:transparent;color:var(--text-2);display:flex;align-items:center;justify-content:center;position:relative}
  .icon-btn:hover{background:#F0F2F5;color:var(--text)}
  .badge-dot{position:absolute;top:4px;right:4px;background:var(--danger);color:#fff;border-radius:99px;font-size:9.5px;font-weight:700;min-width:16px;height:16px;display:flex;align-items:center;justify-content:center;padding:0 4px;border:2px solid #fff}
  .avatar{width:30px;height:30px;border-radius:50%;background:var(--brand);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0}
  .avatar.a0{background:#9CA3AF}
  /* A photo rather than initials. `color:transparent` because the element
     keeps its aria-label for screen readers but must not paint text over the
     image if one ever slips through. */
  .avatar.photo{background-size:cover;background-position:center;background-repeat:no-repeat;color:transparent}
  .avatar.sm{width:26px;height:26px;font-size:10.5px}
  .shell-body{flex:1;display:flex;overflow:hidden}
  .leftnav{width:76px;background:var(--surface);border-right:1px solid var(--border);padding:8px 6px;display:flex;flex-direction:column;gap:2px;flex-shrink:0;overflow-y:auto}
  .nav-item{display:flex;flex-direction:column;align-items:center;gap:5px;padding:10px 2px 8px;border-radius:8px;border:none;background:transparent;color:var(--text-2);font-size:10.5px;font-weight:500;width:100%;line-height:1.15;text-align:center}
  .nav-item:hover{background:#F0F2F5;color:var(--text)}
  .nav-item.active{background:var(--brand-soft);color:var(--brand);font-weight:600}
  .nav-sep{height:1px;background:var(--border);margin:8px 10px;flex-shrink:0}
  .main{flex:1;overflow-y:auto;padding:24px 28px}
  .main.no-pad{padding:0;overflow:hidden;display:flex;flex-direction:column}
  .page-head{display:flex;align-items:center;gap:12px;margin-bottom:18px}
  .page-head h2{font-size:20px;font-weight:600}
  .home-greet{font-size:30px!important;font-weight:500!important}
  .page-head .count{color:var(--text-3);font-size:13px;font-weight:400}
  .page-head .actions{margin-left:auto;display:flex;gap:8px;align-items:center}
  .btn-brand-sm{background:var(--brand);color:#fff;border:none;border-radius:6px;padding:8px 14px;font-size:13px;font-weight:600;display:inline-flex;align-items:center;gap:7px}
  .btn-brand-sm:hover{background:var(--brand-hover)}
  .view-toggle{display:flex;border:1px solid var(--border);border-radius:7px;overflow:hidden}
  .view-toggle button{border:none;background:#fff;color:var(--text-3);width:34px;height:32px;display:flex;align-items:center;justify-content:center}
  .view-toggle button.on{background:var(--brand-soft);color:var(--brand)}
  .view-toggle button:not(:last-child){border-right:1px solid var(--border)}
  .section-title{font-size:15px;font-weight:600;margin:22px 0 12px;display:flex;align-items:center;gap:8px}
  .section-title:first-of-type{margin-top:0}
  .section-title .sc{color:var(--text-3);font-weight:400;font-size:13px}
  .see-all{margin-left:auto;font-size:12.5px;font-weight:500}
  /* Stacked actions on a section heading, for the group page's "New
     dashboard" / "Add existing" pair. Side by side they crowded the heading
     and read as one long strip of buttons; stacked, the primary action sits
     on top and the secondary one directly under it. align-items:stretch so
     both match the width of the wider label instead of stepping raggedly. */
  .section-actions{margin-left:auto;display:flex;flex-direction:column;gap:6px;align-items:stretch}
  .section-actions .btn{font-size:12.5px;font-weight:500;justify-content:center;white-space:nowrap}
  .tile-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px}
  .tile{background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:hidden;cursor:pointer;transition:box-shadow .15s,border-color .15s;position:relative}
  .tile:hover{box-shadow:0 6px 18px rgba(20,30,60,.09);border-color:#C9D2E0}
  .tile .thumb{height:110px;display:flex;align-items:center;justify-content:center;color:#fff;position:relative}
  .tile .thumb svg.ic{width:34px;height:34px;stroke-width:1.3;opacity:.95}
  .thumb.dash{background:linear-gradient(135deg,#E3A600,#F2C811 55%,#F8DE6A);color:#3A3000}
  .thumb.rep{background:linear-gradient(135deg,#1B5E39,#217346 55%,#3D9E6B);color:#fff}
  .thumb .live-chip{position:absolute;top:8px;left:8px;background:rgba(255,255,255,.92);color:var(--success);font-size:10px;font-weight:700;padding:3px 8px;border-radius:99px;letter-spacing:.4px}
  .tile .t-body{padding:12px 14px}
  .tile .t-name{font-weight:600;font-size:13.5px;margin-bottom:5px;padding-right:4px}
  .tile .t-meta{font-size:12px;color:var(--text-3);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .chip{font-size:11px;background:#F0F2F5;border:1px solid var(--border);border-radius:99px;padding:1.5px 8px;color:var(--text-2)}
  .star{position:absolute;top:8px;right:8px;background:rgba(255,255,255,.92);border:none;border-radius:6px;width:26px;height:26px;color:#B8860B;display:flex;align-items:center;justify-content:center}
  .star.off{color:#9CA3AF}
  .tile-menu-btn{position:absolute;top:8px;right:40px;background:rgba(255,255,255,.92);border:none;border-radius:6px;width:26px;height:26px;color:var(--text-2);display:none;align-items:center;justify-content:center}
  .tile:hover .tile-menu-btn{display:flex}
  .group-card .tile-menu-btn{display:flex}
  .type-tag{font-size:10.5px;font-weight:700;letter-spacing:.4px;border-radius:4px;padding:1.5px 6px;white-space:nowrap}
  .type-tag.d{background:#FCF3CE;color:#8A6D00}
  .type-tag.r{background:#E2F0E8;color:#217346}
  .group-card{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:16px;cursor:pointer;transition:box-shadow .15s;position:relative}
  .group-card:hover{box-shadow:0 6px 18px rgba(20,30,60,.09)}
  .group-card .g-ic{width:38px;height:38px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff;margin-bottom:12px}
  .group-card h4{font-size:14px;font-weight:600;margin-bottom:4px}
  .group-card p{font-size:12.5px;color:var(--text-2);margin-bottom:10px;line-height:1.45;min-height:36px}
  .group-card .g-meta{font-size:12px;color:var(--text-3)}
  .group-card .tile-menu-btn{right:8px}
  /* Viewer */
  .viewer-head{background:var(--surface);border-bottom:1px solid var(--border);padding:10px 18px;display:flex;align-items:center;gap:10px;flex-shrink:0}
  .crumb{font-size:12.5px;color:var(--text-3)}
  .crumb a{color:var(--text-3)}
  .crumb a:hover{color:var(--brand)}
  .viewer-head h3{font-size:15.5px;font-weight:600;display:flex;align-items:center;gap:8px}
  .vh-actions{margin-left:auto;display:flex;align-items:center;gap:4px}
  .viewer-body{flex:1;display:flex;overflow:hidden}
  .iframe-wrap{flex:1;background:#EDEFF2;display:flex;align-items:center;justify-content:center;position:relative}
  .iframe-wrap iframe{width:100%;height:100%;border:none;background:#fff}
  .freshness{position:absolute;bottom:10px;left:12px;background:rgba(255,255,255,.94);border:1px solid var(--border);font-size:11px;color:var(--text-2);border-radius:6px;padding:4px 10px}
  .placeholder-embed{text-align:center;color:var(--text-2);padding:40px;max-width:460px}
  .placeholder-embed .ph-ic{color:var(--text-3);margin-bottom:14px}
  .placeholder-embed .ph-ic svg.ic{width:44px;height:44px;stroke-width:1.2}
  .placeholder-embed h4{font-size:15px;margin-bottom:6px;color:var(--text)}
  .placeholder-embed p{font-size:13px;line-height:1.5}
  .comments-panel{width:360px;border-left:1px solid var(--border);background:var(--surface);display:flex;flex-direction:column;flex-shrink:0}
  .cp-head{padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px}
  .cp-head b{font-size:14px}
  .cp-filter{margin-left:auto;border:1px solid var(--border);border-radius:6px;padding:5px 8px;font-size:12.5px;font-family:inherit;background:#fff;color:var(--text-2)}
  .cp-list{flex:1;overflow-y:auto;padding:14px 16px;display:flex;flex-direction:column;gap:16px}
  .cthread{border:1px solid var(--border);border-radius:10px;padding:12px}
  .cthread.resolved{background:#FAFBFC;border-color:#D7E7DB}
  .resolved-banner{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--success);background:var(--success-soft);border-radius:6px;padding:4px 9px;margin-bottom:10px;font-weight:600}
  .comment{display:flex;gap:10px}
  .comment .c-body{flex:1;min-width:0}
  .c-top{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
  .c-top b{font-size:13px}
  .c-top .desig{font-size:11px;color:var(--text-3)}
  .c-top .time{font-size:11px;color:var(--text-3)}
  .c-text{font-size:13px;line-height:1.5;margin-top:3px}
  .mention{background:var(--brand-soft);color:var(--brand);border-radius:4px;padding:0 4px;font-weight:600;font-size:12.5px}
  .c-actions{display:flex;gap:14px;margin-top:6px}
  .c-actions button{border:none;background:none;color:var(--text-3);font-weight:600;font-size:11.5px;padding:0}
  .c-actions button:hover{color:var(--brand)}
  .replies{margin:10px 0 0 20px;padding-left:14px;border-left:2px solid var(--border);display:flex;flex-direction:column;gap:10px}
  .view-replies{border:none;background:none;color:var(--text-2);font-weight:600;font-size:12px;text-align:left;margin:8px 0 0 42px;padding:0}
  .view-replies:hover{color:var(--brand)}
  .composer{border-top:1px solid var(--border);padding:12px 14px;display:flex;gap:10px;align-items:flex-start}
  .composer textarea{flex:1;border:1px solid var(--border);border-radius:8px;padding:9px 11px;font-family:inherit;font-size:13px;resize:none;height:38px;transition:height .15s}
  /* Tall while focused AND while it holds anything at all.
     :focus alone made every control next to it a moving target. Blur fires
     before the click it was blurred by, so pressing Send - or picking a name
     out of the mention list - first collapsed this box by 34px, dropped the
     composer's top edge by the same amount, and slid the thing being clicked
     out from under the pointer. The mention list suffers worst: it is
     anchored to the composer (bottom:calc(100% + 6px)), so it travels the
     full 34px while the cursor is already on its way down.
     :not(:placeholder-shown) keeps the box still exactly when something is
     about to be clicked - you have always typed something by then - and lets
     it shrink back once it is genuinely empty again, which is the only time
     the compact height is worth having. */
  .composer textarea:focus,
  .composer textarea:not(:placeholder-shown){height:72px}
  .composer textarea:focus{outline:2px solid var(--brand)}
  .composer .send{background:var(--brand);color:#fff;border:none;border-radius:8px;width:38px;height:38px;display:flex;align-items:center;justify-content:center}
  .mention-pop{position:absolute;bottom:calc(100% + 6px);left:12px;right:12px;background:#fff;border:1px solid var(--border);border-radius:10px;box-shadow:0 -8px 26px rgba(20,30,60,.14);padding:5px;z-index:20;max-height:230px;overflow:auto}
  .mp-item{display:flex;align-items:center;gap:10px;padding:7px 9px;border-radius:7px;cursor:pointer}
  .mp-item:hover{background:var(--brand-soft)}
  .reply-bar{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);background:#FAFBFC;border-top:1px solid var(--border);padding:7px 16px}
  .reply-bar .rb-x{margin-left:auto;border:none;background:none;color:var(--text-3);display:flex;padding:2px}
  /* Tables */
  .table-card{background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:visible}
  table{width:100%;border-collapse:collapse;font-size:13px}
  th{text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-3);font-weight:700;padding:11px 16px;border-bottom:1px solid var(--border);background:#FAFBFC}
  td{padding:12px 16px;border-bottom:1px solid var(--border);vertical-align:middle}
  tr:last-child td{border-bottom:none}
  tbody tr:hover td{background:#FAFBFC}
  tr.rowlink{cursor:pointer}
  .row-name{display:flex;align-items:center;gap:10px;font-weight:600}
  .row-name .type-ic{width:30px;height:30px;border-radius:7px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}
  .star-cell{border:none;background:none;color:#B8860B;display:flex;align-items:center}
  .star-cell.off{color:#C6CBD1}
  .row-actions{display:flex;gap:4px;justify-content:flex-end}
  .row-actions .icon-btn{width:30px;height:30px}
  .person{display:flex;align-items:center;gap:10px}
  .person .p-n{font-weight:600}
  .person .p-e{font-size:11.5px;color:var(--text-3)}
  .role-badge{font-size:11px;font-weight:700;border-radius:99px;padding:2.5px 10px;white-space:nowrap}
  .role-badge.sa{background:#FCE7F3;color:#BE185D}
  .role-badge.ad{background:var(--brand-soft);color:var(--brand)}
  .role-badge.me{background:#F0F2F5;color:var(--text-2)}
  .status-b{font-size:11.5px;display:inline-flex;align-items:center;gap:5px;color:var(--text-2);white-space:nowrap}
  .status-b::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--success)}
  .status-b.pending::before{background:#D97706}
  .status-b.off::before{background:#9CA3AF}
  .tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);margin-bottom:16px}
  .tab{border:none;background:none;padding:9px 16px;font-size:13.5px;font-weight:500;color:var(--text-2);border-bottom:2px solid transparent}
  .tab.active{color:var(--brand);border-bottom-color:var(--brand);font-weight:600}
  /* Settings */
  /* `align-items:start` used to let every card shrink to its own content, so
     the two cards in a row ended at different heights and the grid looked
     ragged - most obviously Profile vs Password, and Licence vs Email
     notifications once the Licence card landed. Dropping it restores the grid
     default (stretch), which makes both cards in a row exactly as tall as the
     taller one. */
  .settings-grid{display:grid;grid-template-columns:280px 1fr;gap:20px}
  /* A flex column so the extra height a stretched card gains can be given to
     something deliberately, rather than just appearing under the last
     element. */
  .settings-card{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:20px;display:flex;flex-direction:column}
  /* The card's action sits on the bottom edge, so the buttons of both cards
     in a row line up with each other instead of floating at whatever height
     their own fields happened to end. align-self keeps it content-width -
     without it the flex column would stretch it across the whole card. */
  .settings-card > .btn-brand-sm:last-child{margin-top:auto;align-self:flex-start}
  /* The one card with no action. Its rows take the slack instead, spreading
     to the card's full height rather than leaving a hole beneath them. */
  .settings-card > .lic-rows:last-child{flex:1;justify-content:space-between}
  .settings-card h4{font-size:14.5px;font-weight:600;margin-bottom:4px;display:flex;align-items:center;gap:8px}
  .settings-card .sc-sub{font-size:12.5px;color:var(--text-2);margin-bottom:16px}
  .color-row{display:flex;align-items:center;gap:12px;margin-bottom:14px;flex-wrap:wrap}
  .color-row input[type=color]{width:44px;height:34px;border:1px solid var(--border);border-radius:6px;padding:2px;background:#fff}
  .swatches{display:flex;gap:8px}
  .swatch{width:28px;height:28px;border-radius:6px;border:2px solid transparent;cursor:pointer}
  .swatch.sel{border-color:var(--text)}
  .preview-bar{border:1px solid var(--border);border-radius:8px;overflow:hidden;margin-top:6px}
  .preview-bar .pb-top{background:var(--surface);border-bottom:1px solid var(--border);padding:9px 12px;display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600}
  .preview-bar .pb-body{padding:14px 12px;display:flex;gap:8px}
  /* Popovers & modals */
  .notif-pop{position:fixed;top:56px;right:14px;width:400px;background:#fff;border:1px solid var(--border);border-radius:12px;box-shadow:0 16px 44px rgba(20,30,60,.16);z-index:80;display:none;overflow:hidden}
  .notif-pop.open{display:block}
  .np-head{padding:10px 13px;border-bottom:1px solid var(--border);display:flex;align-items:center}
  .np-head b{font-size:13px}
  .np-head button{margin-left:auto;border:none;background:none;color:var(--brand);font-size:11.5px;font-weight:600;cursor:pointer;padding:0}
  .np-head button:hover{text-decoration:underline}
  /* Scrolls past five. Before this the panel had overflow:hidden and no
     height limit, so a long list simply ran off the bottom of the window
     with no way to reach anything older. */
  #notifList{max-height:calc(var(--np-item-h) * 5);overflow-y:auto;overscroll-behavior:contain}
  .np-item{display:flex;gap:11px;padding:12px 15px;border-bottom:1px solid var(--border);cursor:pointer;height:var(--np-item-h);box-sizing:border-box;align-items:center;overflow:hidden}
  .np-item:hover{background:#FAFBFC}
  .np-item:last-child{border-bottom:none}
  .np-item.unread{background:var(--brand-soft)}
  /* min-width:0 lets the clamp below actually clamp - without it the flex
     child refuses to shrink below its text's intrinsic width. */
  .np-item .np-body{min-width:0}
  /* Two lines, then an ellipsis. This is what makes every row exactly
     --np-item-h tall, which is what makes "five" a real number rather than
     an approximation that drifts with however long the text happens to be. */
  .np-item .np-t{font-size:12.5px;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .np-item .np-time{font-size:11px;color:var(--text-3);margin-top:3px}
  /* Where a notification lands. Two and a half seconds of a fading tint,
     long enough to find with your eye and short enough not to become part
     of the page - a permanent highlight would still be sitting there when
     somebody scrolled back an hour later, reading as a state the comment is
     in rather than as the answer to "which one?".

     **The padding is the whole difference between this looking deliberate
     and looking broken.** `.comment` is a bare flex row with no padding of
     its own, so a background on it paints hard against the avatar and the
     text - and inside `.replies`, which already draws its own border-left,
     it lands right on top of that line. The negative margin cancels the
     padding exactly, so the tint grows outward into the gap instead of
     moving the comment or anything below it.

     No left accent bar, for the same reason: `.replies` has one already,
     and a second one 3px inside it reads as a rendering fault. */
  @keyframes commentFlash{
    0%, 62% {background:var(--brand-soft)}
    100%    {background:transparent}
  }
  .comment.flash{
    animation:commentFlash 2.6s ease-out forwards;
    border-radius:8px;
    padding:9px 11px;
    margin:-9px -11px;
  }
  @media (prefers-reduced-motion:reduce){
    .comment.flash{animation:none;background:var(--brand-soft)}
  }
  .np-empty{color:var(--text-3);font-size:12.5px;padding:14px;margin:0}
  .modal-veil{position:fixed;inset:0;background:rgba(15,20,30,.42);z-index:90;display:none;align-items:center;justify-content:center}
  .modal-veil.open{display:flex}
  .modal{background:#fff;border-radius:12px;width:520px;max-width:94vw;box-shadow:0 24px 60px rgba(10,20,40,.3);overflow:hidden;display:flex;flex-direction:column;max-height:88vh}
  .modal.wide{width:600px}
  .modal-head{padding:16px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;flex-shrink:0}
  .modal-head b{font-size:15px}
  .modal-head .x{margin-left:auto;border:none;background:none;color:var(--text-3);display:flex}
  .modal-body{padding:18px 20px;overflow-y:auto}
  .modal-foot{padding:14px 20px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:8px;align-items:center;flex-shrink:0}
  .impact{font-size:12.5px;color:var(--text-2);margin-right:auto}
  .share-user{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:8px}
  .share-user:hover{background:#FAFBFC}
  .share-user label{margin-left:auto}
  .scope-box{border:1px solid var(--border);border-radius:8px;padding:12px 14px;margin-top:8px;font-size:13px}
  .scope-box .sr{display:flex;align-items:center;gap:8px;padding:5px 0}
  /* .fhint is scoped to .field, so the Share dialog's item picker - which is
     not inside one - needs its own rule rather than a looser .fhint that
     every form would inherit. Same reasoning as the .grp-pick fix on 21 Sep:
     scope the new rule, do not widen the old one. */
  .scope-box .fhint{font-size:11.5px;color:var(--text-3);margin-top:6px;line-height:1.4}
  .scope-box #shareItemsWrap{margin-top:8px;padding-left:24px}
  .scope-box .sr input[type=radio]:disabled+label{color:var(--text-3)}
  .access-group{border:1px solid var(--border);border-radius:8px;padding:12px 14px;margin-bottom:10px}
  .access-group .ag-head{display:flex;align-items:center;gap:10px;font-weight:600;font-size:13.5px;cursor:pointer;user-select:none}
  .ag-chev{border:none;background:none;color:var(--text-3);display:flex;align-items:center;padding:2px;transition:transform .15s}
  .ag-chev.open{transform:rotate(90deg)}
  .ag-all{margin-left:auto;display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:500;color:var(--text-2);cursor:pointer;white-space:nowrap}
  .access-items{margin-top:10px;padding-top:6px;border-top:1px dashed var(--border);display:flex;flex-direction:column}
  .access-items label{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--text-2);padding:6px 4px;border-radius:6px}
  .access-items label:hover{background:#FAFBFC}
  .access-items label.dim{opacity:.55}
  .access-items .ai-name{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text)}
  .access-items .ai-type{font-size:10px;font-weight:700;letter-spacing:.3px;color:var(--text-3);flex-shrink:0}
  /* Group pickers: the asset editor's "which groups is this in" checkbox
     list (D-03 - more than one is allowed), and the group page's "add an
     existing dashboard/report" dialog. Scrolls rather than growing the
     modal past the viewport once a tenant has more than a handful. */
  .grp-pick-list{display:flex;flex-direction:column;max-height:240px;overflow-y:auto;border:1px solid var(--border);border-radius:8px;padding:4px}
  /* Selectors deliberately more specific than `.field label` and
     `.field input`, which otherwise win on specificity (0,1,1 against a bare
     class's 0,1,0) and wreck these rows: the label reverts to display:block so
     the flex layout is ignored, and the checkbox inherits width:100% and
     stretches across the row, which is what pushed it to the far right of the
     Groups box. Both are scoped to the list so the field's own caption and
     real text inputs keep the styling they are meant to have. */
  .grp-pick-list label.grp-pick,.ms-panel label.grp-pick{display:flex;align-items:center;gap:9px;font-size:13px;font-weight:400;color:var(--text);padding:7px 8px;margin:0;border-radius:6px;cursor:pointer}
  .grp-pick-list label.grp-pick:hover,.ms-panel label.grp-pick:hover{background:#FAFBFC}
  .grp-pick-list label.grp-pick>span,.ms-panel label.grp-pick>span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .grp-pick-list input[type=checkbox],.ms-panel input[type=checkbox]{width:auto;flex-shrink:0;margin:0;padding:0}

  /* Multi-select field (the asset editor's Groups picker).
     The panel expands IN FLOW rather than floating over the form: .modal is
     overflow:hidden with a scrolling body, so an absolutely positioned panel
     would be clipped the moment the field sat low enough in a tall form, and
     worse on a short screen. In flow it simply pushes the rest down and the
     modal body scrolls, which behaves the same at every height. */
  .ms-control{width:100%;min-height:42px;display:flex;align-items:center;gap:8px;padding:8px 12px;border:1px solid var(--border);border-radius:6px;background:#fff;font-family:inherit;font-size:14px;color:var(--text);text-align:left;cursor:pointer}
  .ms-control:hover{border-color:var(--brand)}
  .ms.open .ms-control{outline:2px solid var(--brand);outline-offset:-1px;border-color:var(--brand)}
  .ms-chips{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px}
  .ms-ph{color:var(--text-3)}
  .ms-chip{background:var(--brand-soft);color:var(--brand);border-radius:5px;padding:2px 8px;font-size:12px;font-weight:600;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ms-caret{flex-shrink:0;display:flex;color:var(--text-3);transition:transform .15s}
  .ms.open .ms-caret{transform:rotate(180deg)}
  .ms-panel{margin-top:6px;border:1px solid var(--border);border-radius:8px;padding:4px;max-height:200px;overflow-y:auto;background:#fff}
  .ms-empty{color:var(--text-3);font-size:12px;padding:8px}
  .checkrow{display:flex;align-items:center;gap:8px;font-size:13px;padding:4px 0}
  .warn-note{background:#FFF8E6;border:1px solid #F0E0B0;color:#7A5E00;font-size:12px;border-radius:6px;padding:8px 12px;margin-top:10px;line-height:1.45}
  .ctx-menu{position:fixed;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 12px 34px rgba(20,30,60,.16);z-index:110;min-width:180px;padding:5px;display:none}
  .ctx-menu.open{display:block}
  .ctx-menu button{display:flex;align-items:center;gap:9px;width:100%;border:none;background:none;padding:8px 11px;font-size:13px;border-radius:6px;color:var(--text);text-align:left}
  .ctx-menu button:hover{background:#F3F4F6}
  .ctx-menu button.danger{color:var(--danger)}
  .ctx-menu .cm-sep{height:1px;background:var(--border);margin:4px 6px}
  /* max-width added with FR-CON-04: the embed-host refusal names the four
     permitted hosts, which is far longer than any toast before it and would
     otherwise render wider than a phone screen. A max-width cannot affect a
     toast whose content is already narrower, so every existing message is
     unchanged. */
  .toast{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);background:var(--text);color:#fff;font-size:13px;padding:10px 18px;border-radius:8px;z-index:150;display:none;box-shadow:0 8px 24px rgba(0,0,0,.25);max-width:min(520px,calc(100vw - 32px));text-align:center;line-height:1.45}
  .toast.show{display:block;animation:tin .2s ease}
  @keyframes tin{from{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%,0)}}
  @media(max-width:1100px){.comments-panel{display:none}.settings-grid{grid-template-columns:1fr}}

  /* ================= Audit log (Phase 6) ================= */
  /* The only page with a subtitle under its heading, so .page-head gets
     top-aligned here rather than globally - every other page is a single
     line and would shift if this changed for all of them. */
  .page-head:has(.sub){align-items:flex-start}
  .page-head:has(.sub) .actions{align-self:flex-start}
  .page-head .sub{color:var(--text-2);font-size:13px;margin-top:4px;font-weight:400}
  .scope-note{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-2);background:#fff;border:1px solid var(--border);border-radius:8px;padding:9px 13px;margin:16px 0}
  .scope-note svg{color:var(--brand);flex-shrink:0}
  .filter-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px}
  .seg{display:flex;border:1px solid var(--border);border-radius:7px;overflow:hidden;background:#fff}
  .seg button{border:none;background:#fff;color:var(--text-2);padding:7px 13px;font-size:12.5px;font-weight:500;border-right:1px solid var(--border)}
  .seg button:last-child{border-right:none}
  .seg button.on{background:var(--brand-soft);color:var(--brand);font-weight:600}
  .fbox{display:flex;align-items:center;gap:7px;border:1px solid var(--border);border-radius:7px;padding:7px 11px;background:#fff;font-size:12.5px;color:var(--text-2)}
  .fbox input[type=date]{border:none;background:none;font-family:inherit;font-size:12.5px;color:var(--text);outline:none;padding:0;width:auto}
  .fsearch{display:flex;align-items:center;gap:7px;border:1px solid var(--border);border-radius:7px;padding:7px 11px;background:#fff;flex:1;min-width:200px;max-width:320px}
  .fsearch input{border:none;outline:none;font-family:inherit;font-size:12.5px;width:100%;padding:0;background:none}
  .clear-filters{font-size:12.5px;color:var(--brand);font-weight:600;background:none;border:none}
  .audit-card{background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:hidden}
  .audit-card table{width:100%;border-collapse:collapse;font-size:13px}
  .audit-card th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-3);font-weight:700;padding:10px 14px;border-bottom:1px solid var(--border);background:#FAFBFC;white-space:nowrap}
  .audit-card td{padding:11px 14px;border-bottom:1px solid var(--border);vertical-align:middle;white-space:nowrap}
  .audit-card tbody tr{cursor:pointer}
  .audit-card tbody tr:hover td{background:#FAFBFC}
  .audit-card tbody tr.expanded td{background:#F7F9FC}
  .audit-card .when{color:var(--text-2);font-size:12.5px}
  .audit-card .when b{color:var(--text);font-weight:600;font-size:13px}
  .stream-badge{font-size:10.5px;font-weight:700;letter-spacing:.3px;border-radius:5px;padding:3px 8px;display:inline-flex;align-items:center;gap:5px}
  .stream-badge.AUTH{background:var(--brand-soft);color:var(--brand)}
  .stream-badge.ASSET_ACCESS{background:#FCF3CE;color:#8A6D00}
  .stream-badge.ADMIN{background:#F0E8FB;color:#6B32B8}
  .event-label{font-weight:500;white-space:normal}
  .outcome{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600}
  .outcome::before{content:"";width:7px;height:7px;border-radius:50%}
  .outcome.SUCCESS{color:var(--success)}
  .outcome.SUCCESS::before{background:var(--success)}
  .outcome.FAILURE{color:var(--danger)}
  .outcome.FAILURE::before{background:var(--danger)}
  .audit-actor{display:flex;align-items:center;gap:8px}
  .audit-actor .av{width:22px;height:22px;border-radius:50%;background:var(--brand);color:#fff;font-size:9.5px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}
  .audit-actor .av.unknown{background:#9CA3AF}
  .actor-name{font-weight:500}
  .actor-name .email-only{color:var(--text-3);font-weight:400;font-style:italic}
  .audit-target .t-type{color:var(--text-3);font-size:11.5px}
  .ipcountry{display:flex;align-items:center;gap:6px;color:var(--text-2);font-size:12.5px}
  .ipcountry .flag{font-size:13px}
  .audit-card tr.expanded .chev{transform:rotate(90deg)}
  .audit-card .chev{color:var(--text-3);transition:transform .15s}
  .detail-row td{white-space:normal;padding:0;background:#F7F9FC}
  .detail-row .inner{padding:14px 18px 18px 44px;border-top:1px dashed var(--border);display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;font-size:12.5px}
  .detail-row .dfield b{display:block;font-size:10.5px;text-transform:uppercase;letter-spacing:.4px;color:var(--text-3);margin-bottom:3px;font-weight:700}
  .detail-row .dfield div{color:var(--text)}
  .detail-row pre{background:#fff;border:1px solid var(--border);border-radius:6px;padding:9px 11px;font-size:11.5px;font-family:ui-monospace,Consolas,monospace;overflow-x:auto;color:var(--text-2);white-space:pre-wrap}
  .event-id{font-family:ui-monospace,Consolas,monospace;font-size:11px;color:var(--text-3)}
  .table-foot{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-top:1px solid var(--border);font-size:12.5px;color:var(--text-2)}
  .pager{display:flex;gap:6px}
  .pager button{border:1px solid var(--border);background:#fff;border-radius:6px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;color:var(--text-2)}
  .pager button:hover:not(:disabled){background:#F3F4F6}
  .pager button:disabled{opacity:.4;cursor:default}
  .pager button.on{background:var(--brand-soft);color:var(--brand);border-color:var(--brand-soft);font-weight:600}
  .audit-empty{text-align:center;padding:60px 20px;color:var(--text-2)}
  .audit-empty svg{color:var(--text-3);margin-bottom:12px}
  .audit-empty h4{font-size:15px;color:var(--text);margin-bottom:5px}
  @media(max-width:900px){.audit-card{overflow-x:auto}}
