*{box-sizing:border-box;}
[hidden]{display:none !important;}
body{
  margin:0; min-height:100vh;
  font-family:"Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  background:var(--bg); color:var(--text); line-height:1.6;
}
a{color:inherit;}
.container{max-width:900px; margin:0 auto; padding:0 24px;}

.topbar{border-bottom:1px solid var(--border); background:var(--surface); position:sticky; top:0; z-index:20;}
.topbar-inner{
  max-width:900px; margin:0 auto; padding:0 24px; height:64px;
  display:flex; align-items:center; justify-content:space-between;
}
.topbar-right{display:flex; align-items:center; gap:16px;}
.logo{font-weight:700; font-size:1.1rem; display:flex; align-items:center; gap:8px;}
.logo-mark{color:var(--accent);}
.user-box{display:flex; align-items:center; gap:14px; font-size:.88rem; color:var(--text-dim);}
.icon-btn{
  display:flex; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:9px; color:var(--text-dim);
  transition:background .15s, color .15s;
}
.icon-btn:hover{background:var(--surface-2); color:var(--text);}

.role-badge{
  display:inline-block; font-size:.68rem; font-weight:800; letter-spacing:.05em;
  padding:2px 9px; border-radius:999px; color:#fff; vertical-align:middle;
}
.role-badge-admin{background:linear-gradient(135deg, #ec4899, #f472b6); box-shadow:0 0 10px rgba(236,72,153,.6);}
.role-badge-owner{background:linear-gradient(135deg, #d4af37, #f5d576); box-shadow:0 0 10px rgba(212,175,55,.6); color:#3a2c00;}

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:10px 18px; border-radius:9px; font-size:.9rem; font-weight:600;
  border:1px solid transparent; cursor:pointer; transition:all .15s;
}
.btn-primary{background:var(--accent); color:#05261d;}
.btn-primary:hover{filter:brightness(1.12);}
.btn-ghost{background:none; color:var(--text-dim); border:none;}
.btn-ghost:hover{color:var(--text);}
.btn-outline{border-color:var(--border); background:none; color:var(--text);}
.btn-outline:hover{border-color:var(--accent); color:var(--accent);}
.btn-block{width:100%;}

/* auth */
.auth-view{
  display:flex; justify-content:center; align-items:center;
  min-height:calc(100vh - 64px); padding:40px 24px;
}
.auth-shell{
  width:100%; max-width:980px; display:grid; grid-template-columns:1.1fr 1fr;
  background:var(--surface); border:1px solid var(--border); border-radius:20px;
  overflow:hidden; box-shadow:0 24px 60px -20px rgba(0,0,0,.5);
}
.auth-brand{
  position:relative; padding:48px 40px;
  background:
    radial-gradient(circle at 15% 15%, rgba(51,214,166,.16), transparent 45%),
    linear-gradient(160deg, var(--bg-alt), var(--bg) 70%);
  border-right:1px solid var(--border);
  display:flex; align-items:center;
}
.auth-brand-inner{position:relative; z-index:1;}
.auth-brand-mark{display:block; margin-bottom:22px;}
.auth-brand-title{font-size:1.5rem; margin:0 0 10px; letter-spacing:-.01em;}
.auth-brand-tagline{color:var(--text-dim); font-size:1.02rem; line-height:1.6; margin:0 0 32px; max-width:320px;}
.auth-brand-features{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:14px;}
.auth-brand-features li{
  display:flex; align-items:center; gap:11px; font-size:.88rem; color:var(--text-dim);
}
.auth-brand-features svg{
  flex:none; color:var(--accent); background:rgba(51,214,166,.12);
  border-radius:50%; padding:3px; width:22px; height:22px;
}

/* Column, not row: the logo now sits above the card rather than beside it. */
.auth-panel{display:flex; flex-direction:column; justify-content:center; align-items:stretch; padding:48px 40px;}
.auth-card{width:100%;}

.auth-tabs{display:flex; gap:8px; margin-bottom:24px; background:var(--bg); border-radius:9px; padding:4px;}
.auth-tab{
  flex:1; padding:9px; border:none; background:none; color:var(--text-dim);
  border-radius:7px; cursor:pointer; font-weight:600; font-size:.88rem;
  transition:background .15s, color .15s;
}
.auth-tab.active{background:var(--surface-2); color:var(--text);}
.auth-form{display:flex; flex-direction:column; gap:16px;}
.auth-form label{font-size:.84rem; color:var(--text-dim); display:flex; flex-direction:column; gap:6px; font-weight:600;}
.auth-form .hint{font-size:.74rem; color:var(--text-faint); font-weight:400;}
.auth-form input{
  background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:11px 13px; color:var(--text); font-size:.92rem; font-family:inherit;
  transition:border-color .15s, box-shadow .15s;
}
.auth-form input:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(51,214,166,.15);}
.auth-form .btn-primary{padding:12px 18px; font-size:.94rem;}
.form-error{font-size:.82rem; color:var(--danger); min-height:1em; margin:0;}

.checkbox-label{
  flex-direction:row !important; align-items:flex-start; gap:10px !important;
  font-weight:500 !important; cursor:pointer; line-height:1.5;
}
.checkbox-label input[type=checkbox]{margin-top:2px; accent-color:var(--accent); width:16px; height:16px; flex:none;}
.checkbox-label .hint{display:block; margin-top:2px;}

.field-row{display:grid; grid-template-columns:1fr 1fr; gap:12px;}
@media (max-width:480px){ .field-row{grid-template-columns:1fr;} }

/* Sub-choice within Create account - visually lighter than the main
   Log in/Create account tabs so it doesn't read as a second nav level. */
.account-type-tabs{display:flex; gap:6px; margin-bottom:2px;}
.account-type-tab{
  flex:1; padding:7px; border:1px solid var(--border); background:none; color:var(--text-faint);
  border-radius:999px; cursor:pointer; font-weight:600; font-size:.78rem;
  transition:border-color .15s, color .15s;
}
.account-type-tab.active{border-color:var(--accent); color:var(--accent);}

#authStepCredentials h2, #authStepVerify h2{font-size:1.25rem; margin:0 0 6px;}
#authStepVerify > p.hint{font-size:.86rem; margin:0 0 22px;}

.verify-sent-banner{
  display:flex; align-items:center; gap:9px; font-size:.84rem;
  background:rgba(51,214,166,.1); border:1px solid rgba(51,214,166,.3);
  color:var(--accent); border-radius:9px; padding:10px 14px; margin-bottom:18px;
}
.verify-sent-banner svg{flex:none;}
.verify-sent-banner strong{color:var(--text); font-weight:700;}

#authStepVerify .auth-form input[name=code]{
  text-align:center; font-size:1.5rem; letter-spacing:.35em; font-weight:700; padding:13px;
}

@media (max-width:820px){
  .auth-shell{grid-template-columns:1fr; max-width:440px;}
  .auth-brand{display:none;}
}

/* dashboard */
.dashboard-view{padding:48px 24px 80px;}
.dashboard-head{display:flex; align-items:center; justify-content:space-between; margin-bottom:12px;}
.dashboard-head h1{font-size:1.6rem; margin:0;}
.status-link-row{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  font-size:.84rem; color:var(--text-dim); margin-bottom:28px;
}
.status-link-row a{color:var(--accent-2); word-break:break-all;}

.add-monitor-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  margin-bottom:24px;
}

/* Input styling for the form, scoped to the inputs rather than to `label`.
   The previous version styled `.add-monitor-card label` directly, which at
   two levels of specificity quietly beat every class the form set on itself. */
.add-monitor-card input[type=text], .add-monitor-card input[type=url],
.add-monitor-card input[type=number], .add-monitor-card input[type=password],
.add-monitor-card select, .add-monitor-card textarea{
  background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:9px 12px; color:var(--text); font-family:inherit; font-size:.9rem;
}
.add-monitor-card input:focus, .add-monitor-card select:focus, .add-monitor-card textarea:focus{
  outline:none; border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.add-monitor-card input[type=checkbox]{accent-color:var(--accent); width:16px; height:16px;}

/* Still used by the invite form, client branding and the admin pages. These
   used to rely on sitting inside a flex-column parent supplied by the old
   add-monitor rules, so they set their own display now rather than inheriting
   one that no longer exists. */
.inline-row{display:flex; flex-direction:row; gap:20px; flex-wrap:wrap; align-items:flex-end;}
.inline-row label{display:flex; flex-direction:column; gap:6px; flex:1; min-width:180px; font-size:.84rem; color:var(--text-dim);}
.inline-row .hint{font-size:.74rem; color:var(--text-faint); font-weight:400;}
.checkbox-row{display:flex; flex-direction:row; flex-wrap:wrap; gap:10px 20px; align-items:center;}
.checkbox-row label{display:flex; flex-direction:row; align-items:center; gap:8px; font-size:.86rem; color:var(--text-dim);}

.form-actions{display:flex; gap:10px;}

/* --- severity system: one visual language across every check --- */
.sev-ok{color:var(--accent);}
.sev-bad{color:var(--danger);}
.sev-warn{color:var(--warn);}
.sev-idle{color:var(--text-faint);}
.dot{width:7px; height:7px; border-radius:50%; display:inline-block; margin-right:8px; flex:none;}
.dot-ok{background:var(--accent); box-shadow:0 0 7px rgba(51,214,166,.7);}
.dot-bad{background:var(--danger); box-shadow:0 0 7px rgba(239,95,107,.7);}
.dot-warn{background:var(--warn); box-shadow:0 0 7px rgba(242,184,75,.7);}
.dot-idle{background:var(--text-faint);}

/* --- summary stat tiles --- */
.stat-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));
  gap:12px; margin-bottom:26px;
}
.stat-tile{
  background:var(--surface); border:1px solid var(--border); border-radius:12px;
  padding:16px 18px; display:flex; flex-direction:column; gap:6px;
}
.stat-label{font-size:.72rem; text-transform:uppercase; letter-spacing:.06em; color:var(--text-faint); font-weight:700;}
.stat-value{font-size:1.7rem; font-weight:700; line-height:1; color:var(--text);}
.stat-value small{font-size:.9rem; font-weight:600; color:var(--text-faint); margin-left:2px;}
.stat-tile.sev-ok .stat-value{color:var(--accent);}
.stat-tile.sev-bad .stat-value{color:var(--danger);}
.stat-tile.sev-warn .stat-value{color:var(--warn);}

/* --- monitor cards --- */
.monitors-list{display:flex; flex-direction:column; gap:16px;}
.monitor-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  overflow:hidden; transition:border-color .15s;
}
.monitor-card:hover{border-color:var(--accent-dim);}
.monitor-card-head{
  display:flex; align-items:flex-start; justify-content:space-between; gap:14px;
  padding:18px 22px 14px;
}
.monitor-identity{display:flex; align-items:flex-start; gap:14px; min-width:0;}
.monitor-card-head h3{margin:0 0 2px; font-size:1.05rem;}
.monitor-url{
  font-size:.8rem; color:var(--text-faint); text-decoration:none;
  display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:44ch;
}
.monitor-url:hover{color:var(--accent-2);}
.monitor-actions{display:flex; align-items:center; gap:12px; flex:none;}
.monitor-method{
  font-size:.68rem; font-weight:700; letter-spacing:.05em; color:var(--text-faint);
  border:1px solid var(--border); border-radius:6px; padding:3px 7px;
}
.status-pill{
  font-size:.72rem; font-weight:800; letter-spacing:.04em; text-transform:uppercase;
  padding:5px 11px; border-radius:999px; flex:none; margin-top:2px;
}
.status-ok{background:rgba(51,214,166,.14); color:var(--accent);}
.status-bad{background:rgba(239,95,107,.14); color:var(--danger);}
.status-warn{background:rgba(242,184,75,.14); color:var(--warn);}
.status-idle{background:rgba(154,167,189,.14); color:var(--text-dim);}

.monitor-metrics{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(110px, 1fr));
  gap:1px; background:var(--border); border-top:1px solid var(--border); border-bottom:1px solid var(--border);
}
.metric{background:var(--surface); padding:12px 22px; display:flex; flex-direction:column; gap:3px;}
.metric-label{font-size:.68rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-faint); font-weight:700;}
.metric-value{font-size:1.15rem; font-weight:700; color:var(--text);}
.metric-value small{font-size:.75rem; color:var(--text-faint); font-weight:600;}
.metric-value.metric-sm{font-size:.9rem; font-weight:600;}

.monitor-checks{padding:6px 22px;}
.check-row{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:9px 0; border-bottom:1px solid var(--border); font-size:.85rem;
}
.check-row:last-child{border-bottom:none;}
.check-name{display:flex; align-items:center; color:var(--text-dim);}
.check-value{color:var(--text); text-align:right; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:52%;}
.check-off .check-name, .check-off .check-value{color:var(--text-faint);}
.check-off .check-name{padding-left:15px;}

.monitor-card-foot{
  display:flex; gap:18px; flex-wrap:wrap;
  padding:12px 22px; background:var(--bg-alt);
  font-size:.76rem; color:var(--text-faint); border-top:1px solid var(--border);
}

.delete-btn{background:none; border:none; color:var(--text-dim); cursor:pointer; font-size:.85rem;}
.delete-btn:hover{color:var(--danger);}
.empty-state{text-align:center; color:var(--text-faint); padding:60px 0;}

/* --- organization picker --- */
.orgs-view{padding:56px 24px 80px; max-width:1000px; margin:0 auto;}
.orgs-head{margin-bottom:28px;}
.orgs-head h1{font-size:1.7rem; margin:0 0 4px;}
.orgs-head p{color:var(--text-dim); margin:0; font-size:.94rem;}
.orgs-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(200px, 1fr)); gap:16px;}
.org-card{
  background:var(--surface); border:1px solid var(--border); border-radius:16px;
  padding:20px; cursor:pointer; text-align:left; font-family:inherit; color:inherit;
  display:flex; flex-direction:column; gap:14px; transition:border-color .15s, transform .15s;
}
.org-card:hover{border-color:var(--accent); transform:translateY(-2px);}
.org-card-avatar, .org-avatar{
  width:72px; height:72px; border-radius:14px; overflow:hidden; flex:none;
  display:flex; align-items:center; justify-content:center; background:var(--bg-alt);
}
.org-card-avatar img, .org-avatar img{width:100%; height:100%; object-fit:cover;}
.org-avatar-letters{
  font-weight:800; font-size:1.5rem; letter-spacing:.02em; color:#fff;
  background:linear-gradient(135deg, hsl(var(--org-hue) 65% 42%), hsl(var(--org-hue) 70% 28%));
}
.org-card-body h3{margin:0 0 6px; font-size:1rem; line-height:1.3;}
.org-card-meta{margin-bottom:6px;}
.org-card-stats{font-size:.78rem; color:var(--text-faint);}
.org-card-inactive{margin-top:6px; font-size:.74rem; font-weight:700; color:var(--warn);}
.org-card-add{
  align-items:center; justify-content:center; text-align:center;
  border-style:dashed; color:var(--text-faint); gap:8px; min-height:170px;
}
.org-add-plus{font-size:1.9rem; line-height:1; font-weight:300;}

.org-role{
  display:inline-block; font-size:.66rem; font-weight:800; letter-spacing:.05em;
  text-transform:uppercase; padding:2px 8px; border-radius:999px;
  background:var(--surface-2); color:var(--text-dim);
}
.org-role-owner{background:linear-gradient(135deg,#d4af37,#f5d576); color:#3a2c00;}
.org-role-admin{background:linear-gradient(135deg,#ec4899,#f472b6); color:#fff;}

.org-panel{
  margin-top:26px; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:24px;
}
.org-panel-inner{display:grid; grid-template-columns:1fr 1fr; gap:26px; margin-bottom:14px;}
@media (max-width:640px){ .org-panel-inner{grid-template-columns:1fr;} }
.org-panel h2{font-size:1rem; margin:0 0 12px;}
.org-panel form{display:flex; flex-direction:column; gap:12px;}
.org-panel label{font-size:.84rem; color:var(--text-dim); display:flex; flex-direction:column; gap:6px; font-weight:600;}
.org-panel input{
  background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:11px 13px; color:var(--text); font-size:.92rem; font-family:inherit;
}
.org-panel input:focus{outline:none; border-color:var(--accent);}

/* --- org dashboard header --- */
.back-link{
  display:inline-flex; align-items:center; gap:7px; background:none; border:none;
  color:var(--text-dim); font-family:inherit; font-size:.86rem; font-weight:600;
  cursor:pointer; padding:0; margin-bottom:20px;
}
.back-link:hover{color:var(--accent);}
.org-header{display:flex; align-items:center; gap:18px; margin-bottom:26px; flex-wrap:wrap;}
.org-header .org-avatar{width:60px; height:60px; border-radius:13px;}
.org-header-text{flex:1; min-width:0;}
.org-header-text h1{margin:0 0 5px; font-size:1.6rem;}
.org-header-meta{margin:0; display:flex; align-items:center; gap:12px; font-size:.84rem; color:var(--text-faint);}

/* --- organization tabs --- */
.org-tabs{
  display:flex; gap:4px; margin-bottom:26px;
  border-bottom:1px solid var(--border); overflow-x:auto;
  /* Scrolls on narrow screens, but the bar itself was showing a stub
     scrollbar in the corner on desktop - hide the chrome, keep the scroll. */
  scrollbar-width:none; -ms-overflow-style:none;
  /* With the scrollbar hidden there was nothing to say the bar scrolls at
     all, which was survivable at four tabs and stopped being so at six - on
     a phone the last two were simply invisible.
     The two `local` layers scroll with the content and sit on top of the two
     `scroll` shadows, so each shadow only shows while there is more in that
     direction. No JavaScript, and nothing to keep in sync. */
  background:
    linear-gradient(to right, var(--bg), transparent) left center / 28px 100% no-repeat local,
    linear-gradient(to left, var(--bg), transparent) right center / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--accent) 30%, transparent), transparent) left center / 14px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--accent) 30%, transparent), transparent) right center / 14px 100% no-repeat scroll;
}
.org-tabs::-webkit-scrollbar{display:none;}
.org-tab{
  position:relative; flex:none; background:none; border:none; cursor:pointer;
  font-family:inherit; font-size:.9rem; font-weight:600; color:var(--text-faint);
  padding:11px 18px; border-radius:9px 9px 0 0; white-space:nowrap;
  transition:color .15s, background .15s;
}
.org-tab:hover{color:var(--text-dim); background:var(--surface);}
.org-tab.active{color:var(--accent);}
.org-tab.active::after{
  content:""; position:absolute; left:12px; right:12px; bottom:-1px; height:2px;
  background:var(--accent); border-radius:2px 2px 0 0;
}
.org-tabpanel > :first-child{margin-top:0;}
.org-tabpanel .billing-card,
.org-tabpanel .team-card{margin-top:0; margin-bottom:16px;}

.invite-code-row{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin-top:14px; padding-top:14px; border-top:1px solid var(--border);
  font-size:.84rem; color:var(--text-dim);
}
.invite-code-row code{
  background:var(--bg); border:1px solid var(--border); border-radius:7px;
  padding:5px 11px; font-size:.92rem; letter-spacing:.12em; color:var(--accent); font-weight:700;
}

.billing-card{
  margin-top:32px; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:22px;
}
.billing-card h2{font-size:1.05rem; margin:0 0 4px;}
.billing-note{font-size:.85rem; margin:0 0 16px; color:var(--text-dim);}

.team-card{
  margin-top:16px; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:22px;
}
.team-card h2{font-size:1.05rem; margin:0 0 14px;}
.team-card .inline-row{align-items:flex-end;}
.team-card input[type=email], .team-card input[type=text],
.team-card input[type=url], .team-card input[type=tel]{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:9px 12px; color:var(--text); font-family:inherit; font-size:.9rem;
}
.team-card input[type=color]{
  width:100%; height:38px; background:var(--bg); border:1px solid var(--border);
  border-radius:8px; padding:4px; cursor:pointer;
}
.team-card label{font-size:.84rem; color:var(--text-dim); display:flex; flex-direction:column; gap:6px;}
.team-list{margin-top:18px; display:flex; flex-direction:column; gap:8px;}
.team-row{
  display:flex; align-items:center; justify-content:space-between;
  background:var(--bg); border:1px solid var(--border); border-radius:10px;
  padding:10px 14px; font-size:.86rem;
}
.team-row .team-row-meta{color:var(--text-faint); font-size:.78rem;}
/* --- plan cards (mirrors the pricing section on walterssentinel.com) --- */
.billing-head{margin-bottom:20px;}
.plan-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr));
  gap:14px; align-items:stretch;
}
.plan-card{
  position:relative; display:flex; flex-direction:column;
  background:var(--bg); border:1px solid var(--border); border-radius:14px;
  padding:22px 20px;
}
.plan-card.plan-current{border-color:var(--accent); box-shadow:0 0 0 1px var(--accent);}
.plan-badge{
  position:absolute; top:-11px; left:50%; transform:translateX(-50%);
  background:var(--accent); color:#05261d; white-space:nowrap;
  font-size:.68rem; font-weight:800; padding:3px 11px; border-radius:999px;
}
.plan-discount{
  position:absolute; top:-11px; right:-8px; transform:rotate(12deg);
  background:var(--danger); color:#fff; white-space:nowrap;
  font-size:.68rem; font-weight:800; padding:3px 10px; border-radius:999px;
  box-shadow:0 2px 6px rgba(0,0,0,.3);
}
.plan-card h3{margin:0 0 6px; font-size:1.02rem;}
.plan-desc{font-size:.8rem; color:var(--text-dim); margin:0 0 14px; min-height:38px; line-height:1.5;}
.plan-price{font-size:1.7rem; font-weight:700; color:var(--text); margin-bottom:16px; line-height:1;}
.plan-price span{font-size:.8rem; font-weight:500; color:var(--text-faint);}
.plan-features{list-style:none; margin:0 0 18px; padding:0; flex:1;}
.plan-features li{
  position:relative; font-size:.82rem; color:var(--text-dim);
  padding:7px 0 7px 20px; border-bottom:1px solid var(--border);
}
.plan-features li:last-child{border-bottom:none;}
.plan-features li::before{content:"✓"; position:absolute; left:0; color:var(--accent); font-weight:700;}
.billing-foot{margin-top:16px;}

/* --- organization settings --- */
.org-settings-grid{display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-bottom:14px;}
@media (max-width:640px){ .org-settings-grid{grid-template-columns:1fr;} }
#orgSettingsForm label{font-size:.84rem; color:var(--text-dim); display:flex; flex-direction:column; gap:6px; font-weight:600;}
#orgSettingsForm input{
  background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:10px 12px; color:var(--text); font-family:inherit; font-size:.9rem;
}
#orgSettingsForm input:focus{outline:none; border-color:var(--accent);}
.danger-zone{
  margin-top:22px; padding-top:18px; border-top:1px solid var(--border);
}
.danger-zone h3{margin:0 0 6px; font-size:.94rem; color:var(--danger);}
.danger-zone p{margin:0 0 14px; font-size:.82rem; color:var(--text-dim); line-height:1.6;}
.btn-danger{background:var(--danger); color:#fff; border-color:var(--danger);}
.btn-danger:hover{filter:brightness(1.1);}

.client-list{display:flex; flex-direction:column; gap:8px; margin-top:12px;}
.client-row{
  display:flex; align-items:center; justify-content:space-between;
  background:var(--bg); border:1px solid var(--border); border-radius:10px;
  padding:12px 16px;
}
.client-row-name{font-weight:600; font-size:.9rem;}
.client-row-meta{font-size:.78rem; color:var(--text-faint); margin-top:2px;}

.report-output{margin-top:16px;}
.report-table{width:100%; border-collapse:collapse; font-size:.85rem;}
.report-table th, .report-table td{
  text-align:left; padding:10px 12px; border-bottom:1px solid var(--border);
}
.report-table th{color:var(--text-faint); font-weight:600; font-size:.76rem; text-transform:uppercase; letter-spacing:.04em;}

/* Disabled buttons had no visual treatment at all, so a gated action
   (e.g. maintenance on a plan that doesn't include it) looked clickable. */
.btn:disabled, .btn[disabled]{opacity:.45; cursor:not-allowed; filter:saturate(.4);}
.btn:disabled:hover, .btn[disabled]:hover{transform:none;}

/* =========================================================================
   Topbar
   Full-bleed, sticky, translucent. Three zones: identity and where you are
   on the left, navigation in the middle, account on the right. No log-out
   button and no admin link - both live in Settings.
   ========================================================================= */
.app-topbar{
  position:sticky; top:0; z-index:40;
  background:color-mix(in srgb, var(--surface) 82%, transparent);
  border-bottom:1px solid var(--border);
  backdrop-filter:saturate(1.6) blur(16px);
  -webkit-backdrop-filter:saturate(1.6) blur(16px);
}
/* A hairline of brand colour along the very top - the sort of detail that
   reads as considered rather than decorative. */
.app-topbar::before{
  content:''; position:absolute; inset:0 0 auto; height:2px;
  background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 55%, transparent), transparent);
  opacity:.5;
}
.tb-inner{
  max-width:1280px; margin:0 auto; padding:0 26px; height:60px;
  display:flex; align-items:center; gap:22px;
}
.tb-left{display:flex; align-items:center; gap:10px; min-width:0; flex:none;}
.tb-brand{display:flex; align-items:center; gap:10px; color:var(--text); text-decoration:none;}
.tb-mark{
  display:block; width:46px; height:46px; flex:none;
  /* Was border-radius:50% for the old circular mark - the new shield has its
     own outline and transparent corners, so a circular clip would cut its
     points off. */
  transition:transform .2s cubic-bezier(.2,.7,.3,1);
}
.tb-brand:hover .tb-mark{transform:scale(1.06);}
.tb-mark svg, .tb-mark img{display:block; width:100%; height:100%; object-fit:contain;}
.tb-wordmark{font-weight:700; font-size:1rem; letter-spacing:-.018em; white-space:nowrap;}

.tb-crumb-sep{color:var(--text-faint); opacity:.5; font-size:1rem;}
.tb-crumb{
  font-size:.88rem; font-weight:600; color:var(--text-dim);
  max-width:280px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

.tb-nav{display:flex; align-items:center; gap:2px; flex:1; min-width:0;}
.tb-link{
  position:relative; padding:8px 13px; border-radius:9px; text-decoration:none;
  font-size:.875rem; font-weight:600; color:var(--text-faint);
  transition:color .14s ease, background .14s ease;
}
.tb-link:hover{color:var(--text); background:var(--surface-2);}
.tb-link.is-active{color:var(--text);}
.tb-link.is-active::after{
  content:''; position:absolute; left:13px; right:13px; bottom:-18px; height:2px;
  border-radius:2px 2px 0 0; background:var(--accent);
  box-shadow:0 0 12px color-mix(in srgb, var(--accent) 60%, transparent);
}

.tb-right{display:flex; align-items:center; gap:9px; flex:none;}

/* Search reads as a control rather than a mystery icon: it says what it is
   and shows the shortcut. Collapses to just the icon on narrow screens. */
.tb-search{
  display:flex; align-items:center; gap:8px;
  background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:7px 10px; color:var(--text-faint); cursor:pointer; font-family:inherit; font-size:.83rem;
  transition:border-color .14s ease, color .14s ease;
}
.tb-search:hover{border-color:var(--accent-dim); color:var(--text);}
.tb-search kbd{
  font-family:inherit; font-size:.7rem; font-weight:700;
  background:var(--surface); border:1px solid var(--border); border-radius:4px; padding:1px 6px;
}

.tb-account-wrap{position:relative;}
.tb-account{
  display:flex; align-items:center; gap:9px; padding:4px 9px 4px 4px;
  background:none; border:1px solid var(--border); border-radius:999px;
  color:var(--text); cursor:pointer; font-family:inherit;
  transition:border-color .14s ease, background .14s ease;
}
.tb-account:hover{border-color:var(--accent-dim); background:var(--surface-2);}
.tb-account[aria-expanded="true"]{border-color:var(--accent); background:var(--surface-2);}
.tb-account-caret{color:var(--text-faint); flex:none; transition:transform .16s ease;}
.tb-account[aria-expanded="true"] .tb-account-caret{transform:rotate(180deg);}
.tb-avatar{
  display:flex; align-items:center; justify-content:center; flex:none;
  width:28px; height:28px; border-radius:50%;
  background:linear-gradient(135deg, var(--accent), var(--accent-dim));
  color:#04231b; font-size:.7rem; font-weight:800; letter-spacing:.02em;
}
.tb-avatar-img{object-fit:cover; background:var(--surface-2);}
.tb-account-text{display:flex; align-items:center; gap:8px; min-width:0;}
.tb-account-name{
  font-size:.84rem; font-weight:600; max-width:150px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.tb-chip{
  flex:none; font-size:.64rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  padding:3px 8px; border-radius:999px;
  background:color-mix(in srgb, var(--accent) 15%, transparent); color:var(--accent);
}

/* The menu the settings gear now lives inside. */
.tb-menu{
  position:absolute; right:0; top:calc(100% + 9px); z-index:60; min-width:252px;
  background:var(--surface); border:1px solid var(--border); border-radius:13px;
  padding:7px; box-shadow:0 18px 44px -14px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
  animation:tbMenuIn .13s ease-out;
}
.tb-menu[hidden]{display:none;}
@keyframes tbMenuIn{from{opacity:0; transform:translateY(-5px);} to{opacity:1; transform:none;}}
:root[data-motion="reduced"] .tb-menu{animation:none;}

.tb-menu-head{display:flex; align-items:center; gap:11px; padding:10px 11px 11px;}
.tb-menu-id{display:flex; flex-direction:column; min-width:0;}
.tb-menu-name{font-size:.88rem; font-weight:650; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.tb-menu-email{font-size:.76rem; color:var(--text-faint); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.tb-menu-role{
  margin:0 11px 4px; font-size:.66rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color:var(--accent);
}
.tb-menu-sep{height:1px; background:var(--border); margin:6px 4px;}
.tb-menu-item{
  display:flex; align-items:center; gap:11px; padding:9px 11px; border-radius:9px;
  font-size:.87rem; font-weight:550; color:var(--text-dim); text-decoration:none;
  transition:background .12s ease, color .12s ease;
}
.tb-menu-item:hover{background:var(--surface-2); color:var(--text);}
.tb-menu-item svg{flex:none; opacity:.75;}
.tb-menu-quiet{color:var(--text-faint);}

.tb-notice{
  background:color-mix(in srgb, var(--warn) 16%, var(--surface));
  border-bottom:1px solid color-mix(in srgb, var(--warn) 40%, var(--border));
  color:var(--text); font-size:.82rem; text-align:center; padding:7px 16px;
}
.tb-notice a{color:var(--accent-2); text-decoration:underline;}

@media (max-width:900px){
  .tb-crumb, .tb-crumb-sep{display:none;}
}
@media (max-width:860px){
  .tb-search-label, .tb-search kbd{display:none;}
  .tb-search{padding:8px;}
}
@media (max-width:720px){
  .tb-inner{gap:12px; padding:0 16px;}
  .tb-wordmark{display:none;}
  .tb-account-text, .tb-account-caret{display:none;}
  .tb-account{padding:4px; border-color:transparent;}
  .tb-link{padding:8px 10px;}
  .tb-menu{min-width:240px;}
}

/* First run: an account with no organizations. The only way to get one is to
   buy a plan, so this is a buying screen rather than an empty state with a
   button that refuses. */
.first-run{
  background:linear-gradient(150deg, color-mix(in srgb, var(--accent) 8%, var(--surface)), var(--surface));
  border:1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  border-radius:var(--radius); padding:30px; margin-bottom:22px;
  box-shadow:0 1px 2px rgba(0,0,0,.3), 0 18px 44px -24px rgba(0,0,0,.7);
}
.first-run[hidden]{display:none;}
.first-run-head{max-width:64ch; margin-bottom:24px;}
.first-run-head h2{font-size:1.4rem; letter-spacing:-.02em; margin:10px 0 8px;}
.first-run-head p{margin:0; font-size:.92rem; line-height:1.7; color:var(--text-dim);}
.eyebrow-chip{
  display:inline-block; font-size:.68rem; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--accent);
  background:color-mix(in srgb, var(--accent) 14%, transparent);
  padding:4px 11px; border-radius:999px;
}
.first-run-foot{margin:18px 0 0;}
.linkish{
  background:none; border:none; padding:0; font:inherit; cursor:pointer;
  color:var(--accent-2); text-decoration:underline;
}

/* On-demand check button on each monitor. */
.check-now-btn{
  background:none; border:1px solid var(--border); color:var(--text-dim);
  border-radius:8px; padding:4px 11px; font-family:inherit; font-size:.78rem; cursor:pointer;
  transition:color .12s ease, border-color .12s ease;
}
.check-now-btn:hover:not(:disabled){color:var(--accent); border-color:var(--accent-dim);}
.check-now-btn:disabled{opacity:.5; cursor:not-allowed;}
.check-now-btn .ws-spinner{width:11px; height:11px; margin-right:6px;}

/* Uptime figure shown per monitor once there is history to compute it from. */
.uptime-badge{
  display:inline-flex; align-items:center; gap:6px; font-size:.75rem; font-weight:650;
  padding:3px 9px; border-radius:999px; margin-left:8px;
  background:var(--bg); border:1px solid var(--border); color:var(--text-faint);
}
.uptime-badge.good{color:var(--accent); border-color:color-mix(in srgb, var(--accent) 40%, var(--border));}
.uptime-badge.poor{color:var(--warn); border-color:color-mix(in srgb, var(--warn) 40%, var(--border));}
.uptime-badge.bad{color:var(--danger); border-color:color-mix(in srgb, var(--danger) 40%, var(--border));}

/* =========================================================================
   Dashboard chrome
   The header, the stat row and the monitor toolbar. The aim is that a wall
   of forty monitors stays scannable: strong hierarchy, one accent, and a
   filter that works without a round trip.
   ========================================================================= */

.org-header{
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  padding:22px 24px; margin-bottom:22px;
  background:linear-gradient(135deg, color-mix(in srgb, var(--accent) 7%, var(--surface)), var(--surface));
  border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:0 1px 2px rgba(0,0,0,.3), 0 14px 34px -20px rgba(0,0,0,.6);
}
.org-header-text{flex:1; min-width:0;}
.org-header-text h1{
  font-size:1.6rem; letter-spacing:-.025em; margin:0 0 5px;
  overflow-wrap:anywhere;
}
.org-header-meta{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0; font-size:.85rem;}

.back-link{
  display:inline-flex; align-items:center; gap:8px; margin-bottom:18px;
  background:none; border:none; cursor:pointer; font-family:inherit;
  font-size:.86rem; font-weight:600; color:var(--text-faint);
  padding:7px 13px 7px 9px; border-radius:999px;
  transition:color .14s ease, background .14s ease;
}
.back-link:hover{color:var(--text); background:var(--surface);}

/* Stat tiles: the number is the point, so it carries the weight. */
.stat-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(148px, 1fr));
  gap:11px; margin-bottom:18px;
}
.stat-tile{
  position:relative; overflow:hidden;
  background:var(--surface); border:1px solid var(--border); border-radius:13px;
  padding:15px 17px;
  transition:border-color .16s ease, transform .16s cubic-bezier(.2,.7,.3,1);
}
.stat-tile:hover{transform:translateY(-2px); border-color:color-mix(in srgb, var(--accent) 30%, var(--border));}
/* A coloured spine keyed to the tile's severity, so the row reads at a
   glance without needing to parse the labels. */
.stat-tile::before{
  content:''; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--border);
}
.stat-tile.sev-ok::before{background:var(--accent);}
.stat-tile.sev-warn::before{background:var(--warn);}
.stat-tile.sev-bad::before{background:var(--danger);}
.stat-label{
  display:block; font-size:.7rem; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-faint); margin-bottom:7px;
}
.stat-value{
  display:block; font-size:1.85rem; font-weight:800; letter-spacing:-.03em; line-height:1;
  font-variant-numeric:tabular-nums;
}
.stat-value small{font-size:.9rem; font-weight:600; color:var(--text-faint); margin-left:2px; letter-spacing:0;}

.status-link-row{
  display:flex; align-items:center; gap:11px; flex-wrap:wrap;
  background:var(--surface); border:1px solid var(--border); border-radius:11px;
  padding:11px 15px; margin-bottom:14px; font-size:.85rem;
}
.status-link-label{
  font-size:.68rem; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--text-faint);
}
.status-link-row a{color:var(--accent-2); overflow-wrap:anywhere;}
.status-link-row .btn{margin-left:auto;}

/* --- toolbar --- */
.monitor-toolbar{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin-bottom:16px;
}
.monitor-search{
  position:relative; display:flex; align-items:center; gap:9px; flex:1; min-width:230px;
  background:var(--surface); border:1px solid var(--border); border-radius:10px;
  padding:0 12px; color:var(--text-faint);
  transition:border-color .14s ease;
}
.monitor-search:focus-within{border-color:var(--accent); color:var(--accent);}
.monitor-search input{
  flex:1; min-width:0; background:none; border:none; outline:none;
  padding:10px 0; color:var(--text); font-family:inherit; font-size:.9rem;
}
.monitor-search input::-webkit-search-cancel-button{filter:grayscale(1) opacity(.6);}
.search-kbd{
  flex:none; font-family:inherit; font-size:.7rem; font-weight:700; color:var(--text-faint);
  background:var(--bg); border:1px solid var(--border); border-radius:5px; padding:2px 7px;
}
.monitor-search:focus-within .search-kbd{display:none;}

.monitor-filters{display:flex; gap:5px; flex-wrap:wrap;}
.filter-chip{
  display:inline-flex; align-items:center; gap:7px;
  background:var(--surface); border:1px solid var(--border); color:var(--text-faint);
  border-radius:999px; padding:8px 14px; font-family:inherit; font-size:.82rem; font-weight:600;
  cursor:pointer; transition:color .13s ease, border-color .13s ease, background .13s ease;
}
.filter-chip:hover{color:var(--text); border-color:var(--accent-dim);}
.filter-chip.active{color:var(--text); border-color:var(--accent); background:var(--surface-2);}
.filter-chip[hidden]{display:none;}
.filter-count{
  font-size:.72rem; font-weight:800; font-variant-numeric:tabular-nums;
  background:var(--bg); border-radius:999px; padding:1px 7px; min-width:20px; text-align:center;
}
.filter-chip.active .filter-count{background:var(--accent); color:#04231b;}

.monitor-meta{display:flex; align-items:center; gap:8px; font-size:.78rem; color:var(--text-faint);}
.live-dot{
  width:7px; height:7px; border-radius:50%; background:var(--accent); flex:none;
  animation:livePulse 2.4s ease-in-out infinite;
}
@keyframes livePulse{0%,100%{opacity:.35;} 50%{opacity:1;}}
:root[data-motion="reduced"] .live-dot{animation:none; opacity:.8;}

.monitor-empty-filter{
  text-align:center; padding:44px 20px; color:var(--text-faint); font-size:.9rem;
  background:var(--surface); border:1px dashed var(--border); border-radius:var(--radius);
}

@media (max-width:720px){
  .monitor-toolbar{gap:9px;}
  .monitor-meta{width:100%; justify-content:flex-end;}
  .org-header{padding:18px; gap:14px;}
  .org-header-text h1{font-size:1.35rem;}
}

/* The logo above the sign-in card. The brand panel beside it is hidden on
   narrow screens, so without this a phone shows an unbranded box with no way
   back to the marketing site. */
.auth-logo{
  display:inline-flex; align-items:center; gap:10px; align-self:center;
  margin-bottom:20px; padding:7px 15px 7px 8px; border-radius:999px;
  border:1px solid transparent; text-decoration:none; color:var(--text);
  font-weight:700; font-size:1.02rem; letter-spacing:-.015em;
  transition:border-color .15s ease, background .15s ease, transform .15s ease;
}
.auth-logo:hover{
  border-color:var(--border); background:var(--surface); transform:translateY(-1px);
}
.auth-logo svg{display:block; border-radius:50%; flex:none;}

/* The brand panel's mark and wordmark are one link back to the site too. */
.auth-brand-link{display:block; text-decoration:none; color:inherit; transition:opacity .15s ease;}
.auth-brand-link:hover{opacity:.85;}

/* First-run Terms gate. Deliberately spells out the three things people are
   most likely to be caught out by, rather than only linking a wall of text. */
.tos-points{display:flex; flex-direction:column; gap:9px; margin:18px 0;}
.tos-point{
  background:var(--bg); border:1px solid var(--border); border-left:3px solid var(--accent);
  border-radius:10px; padding:12px 15px; font-size:.83rem; line-height:1.6; color:var(--text-faint);
}
.tos-point strong{display:block; color:var(--text); font-weight:650; margin-bottom:3px;}
.tos-agree{margin:18px 0 16px;}
.tos-agree a{color:var(--accent-2); text-decoration:underline;}

/* =========================================================================
   Loading states
   Two shapes, used consistently: a full-page overlay while a page works out
   what to show, and an inline spinner inside a button or under a form while
   one request is in flight. Both respect the reduce-motion preference.
   ========================================================================= */

/* The brand mark, drawn as a pulsing signal arc - the same idea as the logo,
   so waiting still looks like the product rather than a generic spinner. */
.ws-loader{
  position:fixed; inset:0; z-index:90;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:18px;
  background:color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
}
.ws-loader[hidden]{display:none;}
.ws-loader-mark{position:relative; width:56px; height:56px;}
.ws-loader-mark span{
  position:absolute; left:50%; bottom:6px;
  border:2.5px solid transparent; border-top-color:var(--accent); border-radius:50%;
  transform:translateX(-50%);
  animation:wsArc 1.5s cubic-bezier(.4,0,.2,1) infinite;
}
.ws-loader-mark span:nth-child(1){width:16px; height:16px; margin-bottom:8px; animation-delay:0s;}
.ws-loader-mark span:nth-child(2){width:32px; height:32px; margin-bottom:8px; animation-delay:.18s;}
.ws-loader-mark span:nth-child(3){width:48px; height:48px; margin-bottom:8px; animation-delay:.36s;}
.ws-loader-mark i{
  position:absolute; left:50%; bottom:2px; transform:translateX(-50%);
  width:7px; height:7px; border-radius:50%; background:var(--accent);
  animation:wsDot 1.5s ease-in-out infinite;
}
@keyframes wsArc{
  0%,100%{opacity:.18;}
  40%{opacity:1;}
}
@keyframes wsDot{
  0%,100%{opacity:.35; transform:translateX(-50%) scale(.85);}
  40%{opacity:1; transform:translateX(-50%) scale(1);}
}
.ws-loader-text{font-size:.86rem; color:var(--text-faint); letter-spacing:.02em;}

/* Inline spinner, for buttons and form footers. */
.ws-spinner{
  display:inline-block; width:15px; height:15px; vertical-align:-2px;
  border:2px solid color-mix(in srgb, currentColor 28%, transparent);
  border-top-color:currentColor; border-radius:50%;
  animation:wsSpin .7s linear infinite;
}
@keyframes wsSpin{to{transform:rotate(360deg);}}

.ws-inline-status{
  display:flex; align-items:center; gap:9px; justify-content:center;
  margin-top:14px; font-size:.85rem; color:var(--text-faint); min-height:20px;
}
.ws-inline-status[hidden]{display:none;}

.btn .ws-spinner{margin-right:1px;}

/* Motion preference wins: the loader stays, it just stops moving. */
:root[data-motion="reduced"] .ws-loader-mark span,
:root[data-motion="reduced"] .ws-loader-mark i,
:root[data-motion="reduced"] .ws-spinner{animation:none !important;}
:root[data-motion="reduced"] .ws-loader-mark span{opacity:.6;}

/* Idle sign-out warning. Sits above everything, including modals. */
.ws-idle{
  position:fixed; inset:0; z-index:120;
  display:flex; align-items:center; justify-content:center; padding:24px;
  background:rgba(4,10,18,.78); backdrop-filter:blur(4px);
}
.ws-idle[hidden]{display:none;}
.ws-idle-card{
  max-width:420px; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:26px; text-align:center;
  box-shadow:0 24px 60px rgba(0,0,0,.5);
}
.ws-idle-card h2{margin:0 0 8px; font-size:1.1rem;}
.ws-idle-card p{margin:0 0 18px; font-size:.88rem; line-height:1.6; color:var(--text-dim);}
.ws-idle-count{font-size:2rem; font-weight:800; color:var(--warn); display:block; margin-bottom:12px;}

/* Connection banner shown by session.js when the API is unreachable. It
   deliberately does not replace the page - whatever you were looking at
   stays on screen and keeps working the moment the connection returns. */
.net-banner{
  position:fixed; left:50%; bottom:20px; transform:translateX(-50%); z-index:80;
  max-width:min(560px, calc(100vw - 32px));
  background:var(--surface); border:1px solid var(--warn); border-radius:11px;
  padding:11px 18px; font-size:.85rem; color:var(--text-dim);
  box-shadow:0 12px 34px -12px rgba(0,0,0,.7);
}
.net-banner[hidden]{display:none;}

/* ---- Paused monitors & pause control ---- */
.monitor-card.monitor-paused{opacity:.72; border-style:dashed;}
.pause-btn{
  background:none; border:1px solid var(--border); color:var(--text-dim);
  border-radius:8px; padding:4px 11px; font-family:inherit; font-size:.78rem; cursor:pointer;
  transition:color .12s ease, border-color .12s ease;
}
.pause-btn:hover{color:var(--accent); border-color:var(--accent-dim);}
.pause-btn:disabled{opacity:.5; cursor:not-allowed;}

/* Shared by the alert-recipient form and the admin grant form. */
.grant-row{display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap; margin-top:14px;}
.grant-row label{
  display:flex; flex-direction:column; gap:6px; flex:1; min-width:220px;
  font-size:.78rem; color:var(--text-faint); text-transform:uppercase; letter-spacing:.04em;
}
.grant-row input{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:11px 14px; color:var(--text); font-family:inherit; font-size:.92rem;
}
.grant-row input:focus{outline:none; border-color:var(--accent);}

/* ---- Scheduled maintenance ---- */
.card-head-row{display:flex; align-items:flex-start; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-bottom:14px;}
.card-head-row h2{margin:0 0 3px;}
.card-head-row .hint{margin:0; max-width:52ch;}
.maint-row{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  background:var(--bg); border:1px solid var(--border); border-radius:10px;
  padding:12px 15px; margin-top:8px;
}
.maint-row.active{border-color:var(--accent); background:var(--surface-2);}
.maint-when{font-size:.88rem; font-weight:600;}
.maint-meta{font-size:.78rem; color:var(--text-faint); margin-top:2px;}
.maint-state{
  font-size:.68rem; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px; margin-left:8px;
}
.maint-state.live{background:rgba(51,214,166,.14); color:var(--accent);}
.maint-state.upcoming{background:rgba(79,140,255,.14); color:var(--accent-2);}
.maint-state.past{background:rgba(255,255,255,.06); color:var(--text-faint);}

/* ---- Modal (checkout organization picker, admin compose) ----
   Base rules live above the trailing media queries so those still win. */
.modal-backdrop{
  position:fixed; inset:0; z-index:200;
  background:rgba(4,10,18,.72); backdrop-filter:blur(4px);
  display:flex; align-items:center; justify-content:center; padding:24px;
  animation:modalFade .14s ease-out;
}
.modal-backdrop[hidden]{display:none;}
@keyframes modalFade{from{opacity:0}to{opacity:1}}
.modal{
  width:100%; max-width:520px; max-height:calc(100vh - 48px); overflow-y:auto;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:0 24px 60px rgba(0,0,0,.45); padding:24px;
  animation:modalRise .16s ease-out;
}
.modal.modal-wide{max-width:760px;}
@keyframes modalRise{from{transform:translateY(10px); opacity:0}to{transform:none; opacity:1}}
.modal-head{display:flex; align-items:flex-start; justify-content:space-between; gap:14px; margin-bottom:18px;}
.modal-head h2{margin:0 0 4px; font-size:1.12rem;}
.modal-sub{margin:0; font-size:.85rem; color:var(--text-faint);}
.modal-close{
  background:none; border:none; color:var(--text-faint); font-size:1.5rem; line-height:1;
  cursor:pointer; padding:0 4px; border-radius:8px;
}
.modal-close:hover{color:var(--text);}
.modal-foot{display:flex; justify-content:flex-end; gap:10px; margin-top:18px;}

/* Modal form fields. Shared by the admin role editor and the mail composer
   - these used to live only in emails.html's scoped <style>, which left the
   role editor's inputs unstyled. */
.compose-field{margin-bottom:14px;}
.compose-field > label{
  display:block; font-size:.75rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color:var(--text-faint); margin-bottom:6px;
}
.compose-field > input, .compose-field > textarea, .compose-field > select{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:10px;
  padding:11px 13px; color:var(--text); font-family:inherit; font-size:.92rem;
}
.compose-field > textarea{min-height:110px; resize:vertical;}
.compose-field > input:focus, .compose-field > textarea:focus, .compose-field > select:focus{outline:none; border-color:var(--accent);}

.org-choice-list{display:flex; flex-direction:column; gap:8px;}
.org-choice{
  display:flex; align-items:flex-start; gap:12px; cursor:pointer;
  background:var(--bg); border:1px solid var(--border); border-radius:11px; padding:13px 15px;
  transition:border-color .12s ease, background .12s ease;
}
.org-choice:hover{border-color:var(--accent-dim);}
.org-choice input[type=radio]{margin-top:3px; accent-color:var(--accent); flex:none;}
.org-choice:has(input:checked){border-color:var(--accent); background:var(--surface-2);}
.org-choice-body{display:flex; flex-direction:column; gap:3px; min-width:0; flex:1;}
.org-choice-name{font-weight:600; font-size:.92rem;}
.org-choice-meta{font-size:.79rem; color:var(--text-faint);}
.org-choice-tag{
  font-size:.68rem; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color:var(--accent); margin-left:8px;
}
.org-choice-input{
  margin-top:8px; width:100%; background:var(--surface); color:var(--text);
  border:1px solid var(--border); border-radius:9px; padding:9px 12px;
  font-family:inherit; font-size:.9rem;
}
.org-choice-input:focus{outline:none; border-color:var(--accent);}
.org-choice-new{margin-top:8px; border-style:dashed;}

/* The desktop app is a Windows install - no point offering it on a phone,
   and it was overflowing/wrapping badly in the topbar at narrow widths.
   Placed last in the file so it reliably wins over earlier .btn rules. */
@media (max-width:640px){
  .desktop-only-link{display:none !important;}
}

.monitor-note{
  margin:6px 0 0; font-size:.82rem; line-height:1.55; color:var(--text-faint); max-width:70ch;
}
.monitor-tags{display:flex; flex-wrap:wrap; gap:6px; margin-top:8px;}
.tag{
  font-size:.68rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px;
  background:var(--bg); border:1px solid var(--border); color:var(--text-faint);
}

/* Recent-history strip on each monitor -------------------------------------
   Thirty checks, newest on the right. One current status cannot tell you the
   difference between "fine" and "fine at this exact second, after failing all
   morning". */
.strip{
  display:flex; gap:2px; align-items:flex-end; height:26px; margin:12px 0 4px;
}
.strip-bar{
  flex:1; min-width:3px; height:100%; border-radius:2px;
  background:var(--accent); opacity:.85; transition:opacity .1s ease;
}
.strip-bar:hover{opacity:1;}
.strip-bar.degraded{background:var(--warn);}
.strip-bar.down, .strip-bar.error{background:var(--danger);}
/* Absence of data, drawn as absence rather than as a healthy bar. */
.strip-bar.none{background:var(--border); opacity:.4; height:40%;}
.strip-empty{
  align-items:center; justify-content:center; border:1px dashed var(--border);
  border-radius:6px; font-size:.74rem; color:var(--text-faint);
}

/* Rich empty state ---------------------------------------------------------
   The first thing a new customer sees inside an organization, so it explains
   what the product does rather than announcing that a list is empty. */
.empty-state-rich{
  background:linear-gradient(150deg, color-mix(in srgb, var(--accent) 7%, var(--surface)), var(--surface));
  border:1px solid color-mix(in srgb, var(--accent) 22%, var(--border));
  border-radius:var(--radius); padding:40px 36px; text-align:center;
  box-shadow:0 1px 2px rgba(0,0,0,.3), 0 20px 50px -30px rgba(0,0,0,.7);
}
.empty-state-rich[hidden]{display:none;}
.es-icon{
  width:52px; height:52px; margin:0 auto 18px; border-radius:14px;
  display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--accent) 15%, transparent); color:var(--accent);
}
.es-icon svg{width:26px; height:26px;}
.empty-state-rich h2{margin:0 0 9px; font-size:1.3rem; letter-spacing:-.02em;}
.empty-state-rich > p{
  margin:0 auto 28px; max-width:56ch; font-size:.93rem; line-height:1.7; color:var(--text-dim);
}
.es-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr));
  gap:14px; text-align:left; margin-bottom:28px;
}
.es-item{
  background:var(--bg); border:1px solid var(--border); border-radius:11px;
  padding:16px 17px; display:grid; gap:6px;
}
.es-item strong{font-size:.88rem; letter-spacing:-.01em; color:var(--accent);}
.es-item span{font-size:.81rem; line-height:1.6; color:var(--text-faint);}
.es-foot{margin:16px 0 0;}

@media (max-width:640px){
  .empty-state-rich{padding:26px 18px;}
  .es-grid{grid-template-columns:1fr; gap:10px;}
  .empty-state-rich .btn{width:100%; justify-content:center;}
}

/* =========================================================================
   Members
   ========================================================================= */

/* What the roles actually mean. It was written down nowhere, so the only way
   to find out was to promote somebody and watch. */
.role-key{
  display:grid; gap:10px; margin:4px 0 20px;
  background:var(--bg); border:1px solid var(--border); border-radius:11px; padding:15px 17px;
}
.role-key-item{display:flex; align-items:baseline; gap:12px; font-size:.82rem; line-height:1.6; color:var(--text-faint);}
.role-badge{
  flex:none; font-size:.64rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px; min-width:62px; text-align:center;
}
.role-owner{background:color-mix(in srgb, var(--warn) 18%, transparent); color:var(--warn);}
.role-admin{background:color-mix(in srgb, var(--accent) 16%, transparent); color:var(--accent);}
.role-member{background:var(--surface); border:1px solid var(--border); color:var(--text-faint);}

.invite-panel{
  display:grid; grid-template-columns:1fr 1fr; gap:24px;
  padding:18px 0 20px; margin-bottom:8px;
  border-top:1px solid var(--border); border-bottom:1px solid var(--border);
}
.invite-panel-col{display:grid; gap:9px; align-content:start; min-width:0;}
.invite-form{display:flex; gap:8px;}
.invite-form input{
  flex:1; min-width:0; background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:9px 12px; color:var(--text); font-family:inherit; font-size:.88rem;
}
.invite-code-row{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  background:var(--bg); border:1px solid var(--border); border-radius:9px; padding:8px 10px;
}
.invite-code-row code{
  flex:1; min-width:0; font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.92rem; letter-spacing:.08em; color:var(--accent); overflow-wrap:anywhere;
}

.member-row{
  display:flex; align-items:center; gap:14px; padding:13px 0;
  border-bottom:1px solid var(--border);
}
.member-row:last-child{border-bottom:none;}
.member-avatar{
  width:38px; height:38px; border-radius:50%; flex:none; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--accent) 15%, var(--bg));
  color:var(--accent); font-size:.8rem; font-weight:800;
}
.member-avatar img{width:100%; height:100%; object-fit:cover;}
.member-identity{flex:1; min-width:0;}
.member-name{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-size:.92rem; font-weight:600; letter-spacing:-.01em;
}
.member-you{
  font-size:.63rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:2px 7px; border-radius:999px; background:var(--bg);
  border:1px solid var(--border); color:var(--text-faint);
}
.member-meta{font-size:.79rem; color:var(--text-faint); margin-top:3px; overflow-wrap:anywhere;}

@media (max-width:640px){
  .invite-panel{grid-template-columns:1fr; gap:18px;}
  .invite-form{flex-direction:column;}
  .invite-form .btn{width:100%; justify-content:center;}
  .role-key-item{flex-direction:column; gap:5px;}
  .member-row{flex-wrap:wrap;}
  .member-row .delete-btn{width:100%;}
}

/* "Everything in Business, and:" - so the plans read as stacking rather than
   as four near-identical lists a customer has to diff by hand. */
.plan-inherits{
  margin:0 0 12px; padding:8px 12px; border-radius:8px;
  font-size:.78rem; font-weight:700; letter-spacing:-.005em;
  background:color-mix(in srgb, var(--accent) 10%, transparent);
  color:var(--accent);
  border:1px solid color-mix(in srgb, var(--accent) 24%, var(--border));
}

/* Alert delivery settings. Locked blocks are greyed with the plan that
   unlocks them rather than hidden - a setting you cannot see is not a reason
   to upgrade. */
.policy-block{
  padding:20px 0; border-top:1px solid var(--border);
}
.policy-block:first-of-type{border-top:none; padding-top:6px;}
.policy-block.is-locked{opacity:.55;}
.policy-block.is-locked input, .policy-block.is-locked select{cursor:not-allowed;}
.policy-head{display:flex; align-items:center; gap:11px; flex-wrap:wrap; margin-bottom:6px;}
.policy-head h3{margin:0; font-size:1rem; letter-spacing:-.01em;}
.policy-lock{
  font-size:.64rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px;
  background:color-mix(in srgb, var(--warn) 15%, transparent); color:var(--warn);
}
.policy-lock[hidden]{display:none;}
.policy-desc{
  margin:0 0 15px; font-size:.85rem; line-height:1.65; color:var(--text-faint); max-width:74ch;
}
.policy-desc strong{color:var(--text-dim);}
.policy-actions{display:flex; align-items:center; gap:12px; margin-top:12px;}
.policy-block .field-grid{margin-bottom:4px;}
.policy-block input[type=time], .policy-block input[type=text],
.policy-block input[type=email], .policy-block input[type=number],
.policy-block input[type=url], .policy-block select{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:9px 12px; color:var(--text); font-family:inherit; font-size:.88rem;
}

/* =========================================================================
   Tester tools
   Only rendered for nominated addresses while the site is in testing mode.
   Deliberately looks different from the rest of the product, so nobody ever
   mistakes a test organization for a real one.
   ========================================================================= */

.tester-panel{
  background:linear-gradient(150deg, color-mix(in srgb, var(--warn) 10%, var(--surface)), var(--surface));
  border:1px solid color-mix(in srgb, var(--warn) 34%, var(--border));
  border-radius:var(--radius); padding:26px 28px; margin-bottom:22px;
}
.tester-panel[hidden]{display:none;}
.tester-badge{
  display:inline-block; font-size:.66rem; font-weight:800; letter-spacing:.1em;
  text-transform:uppercase; color:var(--warn);
  background:color-mix(in srgb, var(--warn) 16%, transparent);
  padding:4px 11px; border-radius:999px;
}
.tester-head h2{margin:11px 0 8px; font-size:1.25rem; letter-spacing:-.02em;}
.tester-head p{margin:0 0 20px; font-size:.9rem; line-height:1.7; color:var(--text-dim); max-width:72ch;}

.tester-plans{display:grid; grid-template-columns:repeat(auto-fit, minmax(170px, 1fr)); gap:11px;}
.tester-plan{
  display:grid; gap:5px; text-align:left; cursor:pointer;
  background:var(--bg); border:1px solid var(--border); border-radius:11px;
  padding:15px 17px; font-family:inherit; color:var(--text);
  transition:border-color .13s ease, transform .13s ease;
}
.tester-plan:hover:not(:disabled){border-color:var(--warn); transform:translateY(-2px);}
.tester-plan:disabled{opacity:.5; cursor:not-allowed;}
.tester-plan strong{font-size:.95rem; letter-spacing:-.01em;}
.tester-plan span{font-size:.78rem; color:var(--text-faint);}
.tester-plan em{font-style:normal; font-size:.72rem; font-weight:700; color:var(--warn); margin-top:4px;}

.tester-more{margin-top:18px;}
.tester-more summary{
  cursor:pointer; font-size:.85rem; font-weight:600; color:var(--warn);
  padding:6px 0; list-style:none;
}
.tester-more summary::-webkit-details-marker{display:none;}
.tester-more summary::before{content:'+ '; font-weight:800;}
.tester-more[open] summary::before{content:'- ';}
.tester-more ul{margin:10px 0 0; padding-left:20px; display:grid; gap:8px;}
.tester-more li{font-size:.84rem; line-height:1.65; color:var(--text-dim);}

/* Admin side: says why the controls are inert rather than just greying out. */
.tester-warning{
  display:grid; gap:5px; margin:14px 0 18px;
  background:color-mix(in srgb, var(--warn) 10%, var(--bg));
  border:1px solid color-mix(in srgb, var(--warn) 32%, var(--border));
  border-radius:10px; padding:14px 16px;
}
.tester-warning[hidden]{display:none;}
.tester-warning strong{font-size:.88rem; color:var(--warn);}
.tester-warning span{font-size:.83rem; line-height:1.65; color:var(--text-dim);}

/* Marks a test organization everywhere it is listed. */
.test-org-tag{
  font-size:.62rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:2px 8px; border-radius:999px; margin-left:8px;
  background:color-mix(in srgb, var(--warn) 16%, transparent); color:var(--warn);
}

@media (max-width:640px){
  .tester-panel{padding:18px;}
  .tester-plans{grid-template-columns:1fr 1fr;}
}

/* =========================================================================
   Billing
   The tab used to be a heading and a row of buy buttons. It never said when
   the plan ran out, which is the one thing somebody opening a billing page
   is there to find out.
   ========================================================================= */

.org-panel-col{min-width:0; display:grid; gap:12px; align-content:start;}
.org-panel-col h2{margin:0; font-size:1.02rem;}
.bill-hero-main{min-width:0;}
/* Confirmation that a save landed, without a dialog for something routine. */
.inline-status{font-size:.8rem; font-weight:600; color:var(--accent);}
.inline-status[hidden]{display:none;}
.bill-hero{
  background:linear-gradient(150deg, color-mix(in srgb, var(--accent) 10%, var(--surface)), var(--surface));
  border:1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  border-radius:var(--radius); padding:26px 28px; margin-bottom:14px;
  display:grid; gap:20px;
}
.bill-hero[hidden]{display:none;}
/* The border carries the urgency, so the state is legible before reading. */
.bill-hero.is-ending{border-color:color-mix(in srgb, var(--warn) 42%, var(--border));}
.bill-hero.is-expired{border-color:color-mix(in srgb, var(--danger) 45%, var(--border));}
.bill-eyebrow{
  font-size:.66rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-faint);
}
.bill-hero h2{margin:6px 0 8px; font-size:1.65rem; letter-spacing:-.03em;}
.bill-status{margin:0; font-size:.88rem; line-height:1.65; color:var(--text-dim); max-width:70ch;}

/* A bar for the paid period, so "18 days left" has something to be out of. */
.bill-gauge{display:grid; gap:7px;}
.bill-gauge-track{
  height:7px; border-radius:99px; background:var(--bg);
  border:1px solid var(--border); overflow:hidden;
}
.bill-gauge-fill{height:100%; background:var(--accent); border-radius:99px; transition:width .3s ease;}
.bill-gauge-fill.is-ending{background:var(--warn);}
.bill-gauge-fill.is-expired{background:var(--danger);}
.bill-gauge-labels{
  display:flex; justify-content:space-between; font-size:.72rem; color:var(--text-faint);
}

.bill-stats{display:grid; grid-template-columns:repeat(4, 1fr); gap:11px; margin-bottom:14px;}
.bill-stats[hidden]{display:none;}
.bill-stat{
  background:var(--surface); border:1px solid var(--border); border-radius:11px;
  padding:14px 16px; display:grid; gap:5px;
}
.bill-stat-label{
  font-size:.66rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-faint);
}
.bill-stat strong{font-size:1.2rem; letter-spacing:-.02em;}

/* Only appears when an early renewal actually carried time over. */
.bill-carry{
  display:grid; gap:5px; margin-bottom:14px;
  background:color-mix(in srgb, var(--accent) 9%, var(--surface));
  border:1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  border-radius:11px; padding:15px 17px;
}
.bill-carry[hidden]{display:none;}
.bill-carry strong{font-size:.89rem; color:var(--accent);}
.bill-carry span{font-size:.83rem; line-height:1.65; color:var(--text-dim);}

/* =========================================================================
   Organization logo
   ========================================================================= */

.logo-setting{
  display:grid; grid-template-columns:auto 1fr; gap:22px; align-items:start;
  padding:20px 0; margin:6px 0;
  border-top:1px solid var(--border); border-bottom:1px solid var(--border);
}
.logo-preview{
  width:84px; height:84px; border-radius:16px; flex:none;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  background:var(--bg); border:1px solid var(--border);
  font-size:1.6rem; font-weight:800; letter-spacing:-.02em; color:var(--accent);
}
.logo-preview img{width:100%; height:100%; object-fit:contain;}
.logo-controls{display:grid; gap:11px; min-width:0;}
.logo-tabs{display:flex; gap:2px; background:var(--bg); border:1px solid var(--border); border-radius:9px; padding:3px; width:fit-content;}
.logo-tab{
  background:none; border:none; border-radius:7px; padding:6px 14px; cursor:pointer;
  font-family:inherit; font-size:.79rem; font-weight:600; color:var(--text-faint);
  transition:background .12s ease, color .12s ease;
}
.logo-tab.is-active{background:var(--surface); color:var(--accent);}
.logo-controls [data-logo-panel]{display:grid; gap:9px;}
.logo-controls [data-logo-panel][hidden]{display:none;}
.logo-actions{display:flex; gap:8px; flex-wrap:wrap;}
.logo-controls input[type=url]{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:9px 12px; color:var(--text); font-family:inherit; font-size:.88rem;
}
#logoError:empty{display:none;}

@media (max-width:640px){
  .bill-hero{padding:18px; }
  .bill-hero h2{font-size:1.35rem;}
  .bill-stats{grid-template-columns:1fr 1fr;}
  .logo-setting{grid-template-columns:1fr; gap:16px; justify-items:start;}
  .logo-tabs{width:100%;}
  .logo-tab{flex:1;}
}

/* Docs article content ------------------------------------------------------
   .doc-table previously existed only inside a mobile media query, so on a
   desktop it rendered as a bare unstyled table. */
.doc-table{
  width:100%; border-collapse:collapse; font-size:.86rem; margin:14px 0 18px;
}
.doc-table th, .doc-table td{
  text-align:left; padding:9px 12px; border-bottom:1px solid var(--border);
  color:var(--text-dim); vertical-align:top;
}
.doc-table th{
  color:var(--text); font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em;
}
.doc-table tr:last-child td{border-bottom:none;}
.doc-table code{
  background:var(--bg); border:1px solid var(--border); border-radius:4px;
  padding:1px 5px; font-size:.92em;
}
.doc-code{
  background:var(--bg); border:1px solid var(--border); border-radius:9px;
  padding:13px 15px; margin:12px 0 16px; overflow-x:auto;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.83rem; line-height:1.7; color:var(--text-dim); white-space:pre;
}

/* =========================================================================
   Single-message pages
   Verification, password reset, payment result. Each of these used to carry
   an inline `padding-top:100px`, which no stylesheet could override - so on a
   phone the content started 179px down an 812px screen, and the one thing the
   page exists to say was below the fold on the shortest handsets.
   ========================================================================= */

.notice-page{
  width:100%; max-width:420px; margin:0 auto;
  padding:96px 24px 60px;
}
.notice-page.notice-centre{text-align:center;}
.notice-page h1{font-size:1.3rem; letter-spacing:-.02em;}

@media (max-width:640px){
  .notice-page{
    /* Vertically centred in whatever space is left under the header, rather
       than pushed down by a fixed number that was chosen for a desktop. */
    min-height:calc(100vh - 160px);
    min-height:calc(100dvh - 160px);
    display:flex; flex-direction:column; justify-content:center;
    padding:28px 18px 40px;
  }
  /* A single action on a phone should be the full width of the thumb's reach,
     not a small pill floating in the middle. */
  .notice-page > .btn{width:100%; justify-content:center; margin-top:6px;}
  .notice-page form .btn{width:100%; justify-content:center;}
}

/* Short landscape phones have no spare height for vertical centring. */
@media (max-width:900px) and (max-height:480px){
  .notice-page{min-height:0; display:block; padding-top:22px;}
}

/* Email deliverability panel ---------------------------------------------
   Severity carried by colour so the blocking problem is the one the eye lands
   on, rather than three paragraphs that all look equally important. */
.deliv-stamp{margin:0 0 13px; font-size:.78rem;}
.deliv-test{
  margin-top:18px; padding-top:18px; border-top:1px solid var(--border);
}
.deliv-test h3{margin:0 0 4px; font-size:.95rem;}
.deliv-test .hint{margin:0 0 12px;}
.deliv-domain{
  background:var(--bg); border:1px solid var(--border); border-radius:12px;
  padding:17px 19px; margin-bottom:13px;
}
.deliv-domain-head{display:flex; align-items:center; gap:11px; margin-bottom:13px;}
.deliv-domain-head h3{margin:0; font-size:.95rem;}
.deliv-records{display:grid; gap:7px; margin-bottom:15px;}
.deliv-records > div{display:grid; grid-template-columns:64px 1fr; gap:10px; align-items:baseline;}
.deliv-records span{
  font-size:.66rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--text-faint);
}
.deliv-records code{
  font-size:.76rem; color:var(--text-dim); overflow-wrap:anywhere;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
}
.deliv-finding{
  border-radius:10px; padding:13px 15px; margin-top:9px;
  border:1px solid var(--border); background:var(--surface);
}
.deliv-finding strong{font-size:.87rem; display:block; margin-bottom:6px;}
.deliv-finding p{margin:0 0 7px; font-size:.82rem; line-height:1.65; color:var(--text-faint);}
.deliv-finding p:last-child{margin-bottom:0;}
.deliv-fix span{
  font-size:.63rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:2px 7px; border-radius:999px; margin-right:6px;
  background:color-mix(in srgb, var(--accent) 16%, transparent); color:var(--accent);
}
.deliv-danger{border-color:color-mix(in srgb, var(--danger) 42%, var(--border));}
.deliv-danger strong{color:var(--danger);}
.deliv-warn{border-color:color-mix(in srgb, var(--warn) 40%, var(--border));}
.deliv-warn strong{color:var(--warn);}
.deliv-ok{border-color:color-mix(in srgb, var(--accent) 38%, var(--border));}
.deliv-ok strong{color:var(--accent);}
@media (max-width:640px){
  .deliv-records > div{grid-template-columns:1fr; gap:2px;}
}

/* Password reveal --------------------------------------------------------
   Wrapper is added by reveal.js around every password input, so the button
   can sit inside the field without every form having to be laid out for it. */
.pw-wrap{position:relative; display:block; width:100%;}
.pw-wrap input{width:100%; padding-right:44px !important;}
.pw-reveal{
  position:absolute; top:50%; right:4px; transform:translateY(-50%);
  display:flex; align-items:center; justify-content:center;
  width:36px; height:36px; padding:0;
  background:none; border:none; border-radius:8px; cursor:pointer;
  color:var(--text-faint); transition:color .12s ease, background .12s ease;
}
.pw-reveal:hover{color:var(--accent); background:color-mix(in srgb, var(--accent) 10%, transparent);}
.pw-reveal:focus-visible{outline:2px solid var(--accent); outline-offset:1px;}
.pw-reveal svg{width:19px; height:19px;}

/* A thumb needs more than 36px, and on a touch screen there is room for it. */
@media (pointer:coarse){
  .pw-reveal{width:44px; height:44px;}
  .pw-wrap input{padding-right:50px !important;}
}

/* =========================================================================
   Our own dialogs
   Replacing confirm() / prompt() / alert(), which announce
   "app.walterssentinel.com says" above unstyled system text and cannot show
   a customer what they are actually about to destroy.
   ========================================================================= */

.dialog-backdrop{z-index:1200;}
.dialog{max-width:480px;}
.dialog .modal-head{align-items:flex-start;}
.dialog .modal-head h2{font-size:1.15rem; letter-spacing:-.02em;}

/* A destructive dialog looks destructive, rather than looking like every
   other dialog and relying on the customer reading carefully. */
.dialog-danger{border-color:color-mix(in srgb, var(--danger) 45%, var(--border));}
.dialog-icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; border-radius:50%; margin-bottom:9px;
  background:color-mix(in srgb, var(--danger) 16%, transparent);
  color:var(--danger); font-weight:900; font-size:.9rem;
}

.dialog-body{margin-bottom:18px;}
.dialog-body p{margin:0 0 11px; font-size:.9rem; line-height:1.65; color:var(--text-dim);}
.dialog-body p:last-child{margin-bottom:0;}
.dialog-body strong{color:var(--text);}
.dialog-body .hint{font-size:.8rem;}

/* The "did you mean to do the safe thing instead" panel. Most people reaching
   for delete want pause. */
.dialog-alt{
  display:grid; gap:5px; margin:14px 0;
  background:color-mix(in srgb, var(--accent) 9%, var(--bg));
  border:1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  border-radius:10px; padding:13px 15px;
}
.dialog-alt strong{font-size:.86rem; color:var(--accent);}
.dialog-alt span{font-size:.81rem; line-height:1.6; color:var(--text-faint);}

/* What is about to be lost, counted rather than described. */
.dialog-losses{
  display:grid; grid-template-columns:repeat(2, 1fr); gap:9px; margin:15px 0;
}
.dialog-losses > div{
  background:var(--bg); border:1px solid color-mix(in srgb, var(--danger) 22%, var(--border));
  border-radius:9px; padding:11px 13px; display:grid; gap:2px;
}
.dialog-losses strong{font-size:1.05rem; color:var(--danger); letter-spacing:-.02em;}
.dialog-losses span{font-size:.74rem; color:var(--text-faint);}

.dialog-field{margin-bottom:16px;}
.dialog-field input{
  width:100%; background:var(--bg); border:1px solid var(--border); border-radius:8px;
  padding:10px 12px; color:var(--text); font-family:inherit; font-size:.92rem;
}
.dialog-field input:focus{
  outline:none; border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.dialog-field input[readonly]{color:var(--text-dim); cursor:text;}

/* A six-digit code deserves to be readable. Monospace and spaced out so a
   transposed digit is obvious before it is submitted. */
.dialog-code-input{
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace !important;
  font-size:1.5rem !important; letter-spacing:.42em; text-align:center;
  padding:13px 12px !important;
}
.dialog-danger .dialog-field input:focus{
  border-color:var(--danger);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--danger) 18%, transparent);
}

.dialog-error{margin:0 0 14px;}
.dialog-error[hidden]{display:none;}
.dialog .modal-foot{margin-top:0;}

.btn-danger{
  background:var(--danger); border:1px solid var(--danger); color:#fff;
}
.btn-danger:hover:not(:disabled){filter:brightness(1.08);}

@media (max-width:640px){
  .dialog{max-width:100%;}
  .dialog-losses{grid-template-columns:1fr 1fr;}
  .dialog-code-input{font-size:1.3rem !important; letter-spacing:.3em;}
}

/* =========================================================================
   Add / edit monitor
   The old form was two inputs and six unlabelled checkboxes. This one is
   sectioned, every field says what it is for, and the sections are tabs
   rather than one long scroll.
   ========================================================================= */

.add-monitor-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:0; margin-bottom:20px; overflow:hidden;
  box-shadow:0 1px 2px rgba(0,0,0,.3), 0 24px 60px -32px rgba(0,0,0,.75);
}
.add-monitor-card[hidden]{display:none;}

.amc-head{
  display:flex; align-items:flex-start; justify-content:space-between; gap:16px;
  padding:22px 26px 18px;
  background:linear-gradient(150deg, color-mix(in srgb, var(--accent) 8%, var(--surface)), var(--surface));
  border-bottom:1px solid var(--border);
}
.amc-head h2{margin:0 0 5px; font-size:1.18rem; letter-spacing:-.02em;}
.amc-head .hint{margin:0; max-width:60ch;}

/* Step tabs. Numbered so the shape of the task is visible at a glance - five
   sections, four of them optional. */
.amc-steps{
  display:flex; gap:2px; padding:0 26px; overflow-x:auto;
  border-bottom:1px solid var(--border); background:var(--bg);
  scrollbar-width:none;
}
.amc-steps::-webkit-scrollbar{display:none;}
.amc-step{
  display:flex; align-items:center; gap:9px; flex:none;
  background:none; border:none; border-bottom:2px solid transparent;
  padding:14px 16px; margin-bottom:-1px; cursor:pointer;
  font-family:inherit; font-size:.85rem; font-weight:600; color:var(--text-faint);
  transition:color .13s ease, border-color .13s ease;
  white-space:nowrap;
}
.amc-step:hover{color:var(--text-dim);}
.amc-step.is-active{color:var(--accent); border-bottom-color:var(--accent);}
.amc-step-n{
  display:inline-flex; align-items:center; justify-content:center;
  width:21px; height:21px; border-radius:50%; font-size:.7rem; font-weight:800;
  background:var(--surface-2, rgba(255,255,255,.06)); color:inherit;
  border:1px solid var(--border);
}
.amc-step.is-active .amc-step-n{
  background:color-mix(in srgb, var(--accent) 18%, transparent);
  border-color:color-mix(in srgb, var(--accent) 45%, var(--border));
}

.amc-panel{padding:26px; display:grid; gap:20px; align-content:start;}
.amc-panel[hidden]{display:none;}
.amc-lead{
  margin:0; font-size:.88rem; line-height:1.7; color:var(--text-dim); max-width:74ch;
}
.amc-divider{
  display:flex; align-items:center; gap:14px; margin:4px 0 -4px;
  font-size:.7rem; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-faint);
}
.amc-divider::after{content:''; flex:1; height:1px; background:var(--border);}

/* --- fields --- */
/* Two columns where there is room, one where there is not. Used for pairs of
   related fields that read better side by side. */
.btn-sm{padding:6px 13px; font-size:.79rem;}
.field-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(228px, 1fr)); gap:18px;
}
.fld{display:grid; gap:7px; min-width:0;}
.fld-label{
  font-size:.79rem; font-weight:700; letter-spacing:-.005em; color:var(--text);
  display:flex; align-items:baseline; gap:8px;
}
.fld-label em{
  font-style:normal; font-size:.66rem; font-weight:700; text-transform:uppercase;
  letter-spacing:.07em; color:var(--text-faint);
}
.fld-help{font-size:.78rem; line-height:1.6; color:var(--text-faint);}
.fld-help code{
  background:var(--bg); border:1px solid var(--border); border-radius:4px;
  padding:1px 5px; font-size:.92em;
}
.fld input, .fld select, .fld textarea{width:100%;}
.fld textarea{resize:vertical; min-height:64px; font-family:inherit; font-size:.88rem; line-height:1.6;}
/* Monospace only where the content is literally code - headers and request
   bodies. A prose note in monospace reads like a terminal. */
.fld textarea[name=requestHeaders], .fld textarea[name=requestBody]{
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:.85rem;
}
.fld-inline{grid-template-columns:1fr auto; align-items:center; gap:12px;}
.fld-inline input{max-width:96px;}

/* A unit that sits inside the box rather than floating beside it. */
.input-suffix{display:flex; align-items:center; gap:0;}
.input-suffix input{border-radius:8px 0 0 8px; border-right:none;}
.input-suffix > span{
  padding:0 13px; height:var(--control-h, 40px); display:flex; align-items:center;
  background:var(--bg); border:1px solid var(--border); border-left:none;
  border-radius:0 8px 8px 0; font-size:.8rem; color:var(--text-faint); white-space:nowrap;
}

/* --- checkboxes with explanations --- */
.check{
  display:flex; align-items:flex-start; gap:11px; cursor:pointer;
  font-size:.87rem; line-height:1.55;
}
.check input{margin-top:2px; flex:none;}
.check > span{display:grid; gap:3px;}
.check em{font-style:normal; font-size:.78rem; color:var(--text-faint); line-height:1.6;}

.check-cards{display:grid; gap:10px;}
.check-card{
  display:flex; align-items:flex-start; gap:13px; cursor:pointer;
  background:var(--bg); border:1px solid var(--border); border-radius:11px;
  padding:15px 17px; transition:border-color .13s ease, background .13s ease;
}
.check-card:hover{border-color:var(--accent-dim, var(--border));}
.check-card:has(input:checked){
  border-color:color-mix(in srgb, var(--accent) 40%, var(--border));
  background:color-mix(in srgb, var(--accent) 6%, var(--bg));
}
.check-card input{margin-top:3px; flex:none;}
.check-card-body{display:grid; gap:4px;}
.check-card-body strong{font-size:.9rem; letter-spacing:-.01em;}
.check-card-body > span{font-size:.81rem; line-height:1.6; color:var(--text-faint);}

/* A sub-setting greys out with its parent rather than vanishing, so nothing
   jumps around as boxes are ticked. */
.sub-field{
  padding:0 17px 4px 45px; margin-top:-4px;
  transition:opacity .15s ease;
}
.sub-field.is-off{opacity:.35; pointer-events:none;}

.amc-note{
  background:color-mix(in srgb, var(--accent) 8%, var(--bg));
  border:1px solid color-mix(in srgb, var(--accent) 24%, var(--border));
  border-radius:10px; padding:14px 16px; font-size:.85rem; line-height:1.65;
  color:var(--text-dim);
}
.amc-actions{
  padding:20px 26px; border-top:1px solid var(--border); background:var(--bg);
  display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin:0;
}

/* --- the result of "test without saving" --- */
.test-result{
  margin:0 26px 20px; padding:15px 17px; border-radius:11px;
  border:1px solid var(--border); background:var(--bg); font-size:.87rem;
}
.test-result[hidden]{display:none;}
.test-head{display:flex; align-items:center; gap:11px; flex-wrap:wrap; margin-bottom:7px;}
.test-badge{
  font-size:.66rem; font-weight:800; letter-spacing:.08em; text-transform:uppercase;
  padding:3px 10px; border-radius:999px; border:1px solid currentColor;
}
.test-meta{font-size:.8rem; color:var(--text-faint);}
.test-result .hint{margin:9px 0 0;}
.test-result.up{border-color:color-mix(in srgb, var(--accent) 40%, var(--border)); color:var(--accent);}
.test-result.degraded{border-color:color-mix(in srgb, var(--warn) 40%, var(--border)); color:var(--warn);}
.test-result.down, .test-result.error{border-color:color-mix(in srgb, var(--danger) 40%, var(--border)); color:var(--danger);}
.test-result.testing{color:var(--text-faint);}
.test-result strong, .test-result .test-meta{color:var(--text);}

.edit-btn{
  background:none; border:1px solid var(--border); color:var(--text-dim);
  border-radius:8px; padding:4px 11px; font-family:inherit; font-size:.78rem; cursor:pointer;
  transition:color .12s ease, border-color .12s ease;
}
.edit-btn:hover{color:var(--accent); border-color:var(--accent-dim, var(--accent));}

@media (max-width:640px){
  .amc-head{padding:18px 16px 14px; flex-direction:column; gap:12px;}
  .amc-steps{padding:0 16px;}
  .amc-step{padding:13px 12px; font-size:.8rem;}
  .amc-step-t{display:none;}
  .amc-step.is-active .amc-step-t{display:inline;}
  .amc-panel{padding:18px 16px;}
  .amc-actions{padding:16px; flex-direction:column-reverse; align-items:stretch;}
  .amc-actions .btn{width:100%; justify-content:center;}
  .test-result{margin:0 16px 16px;}
  .sub-field{padding-left:17px;}
}

/* Live payments feed --------------------------------------------------------
   The pill states whether the figures are actually live. A dashboard that
   quietly stops updating is worse than one that admits it has. */
.live-pill{
  display:inline-flex; align-items:center; gap:7px; font-size:.72rem; font-weight:700;
  letter-spacing:.03em; padding:5px 12px; border-radius:999px; white-space:nowrap;
  border:1px solid var(--border); color:var(--text-faint); background:var(--bg);
}
.live-pill .live-dot{width:7px; height:7px; border-radius:50%; background:currentColor;}
.live-pill[data-state="live"]{
  color:var(--accent); border-color:color-mix(in srgb, var(--accent) 40%, var(--border));
}
.live-pill[data-state="live"] .live-dot{animation:livePulse 2s ease-in-out infinite;}
.live-pill[data-state="connecting"]{color:var(--warn); border-color:color-mix(in srgb, var(--warn) 35%, var(--border));}
.live-pill[data-state="offline"]{color:var(--danger); border-color:color-mix(in srgb, var(--danger) 35%, var(--border));}
@keyframes livePulse{0%,100%{opacity:1;} 50%{opacity:.3;}}

/* Today's takings, above the ledger. */
.takings{
  display:grid; grid-template-columns:repeat(4, 1fr); gap:14px;
  background:linear-gradient(150deg, color-mix(in srgb, var(--accent) 7%, var(--surface)), var(--surface));
  border:1px solid color-mix(in srgb, var(--accent) 22%, var(--border));
  border-radius:12px; padding:18px 20px; margin:16px 0 20px;
}
.takings[hidden]{display:none;}
.takings-fig{display:flex; flex-direction:column; gap:5px; min-width:0;}
.takings-label{
  font-size:.66rem; text-transform:uppercase; letter-spacing:.08em;
  color:var(--text-faint); font-weight:700;
}
.takings-fig strong{font-size:1.35rem; letter-spacing:-.02em;}
.takings-fig strong.neg{color:var(--text-dim);}
.takings-fig.accent strong{color:var(--accent);}
.takings-note{grid-column:1 / -1; margin:0; padding-top:10px; border-top:1px solid var(--border);}

/* A payment that arrived while you were looking at the page. The flash fades
   rather than staying highlighted - it marks the arrival, it is not a state. */
.list-item.just-in{animation:justIn 2.4s ease-out;}
@keyframes justIn{
  0%{background:color-mix(in srgb, var(--accent) 20%, transparent); transform:translateY(-4px);}
  100%{background:transparent; transform:none;}
}
.pay-net{font-size:.74rem; font-weight:600; color:var(--accent); margin-left:8px;}
.pay-net.pending{color:var(--text-faint); font-weight:500;}

@media (max-width:640px){
  .takings{grid-template-columns:1fr 1fr; padding:15px;}
  .takings-fig strong{font-size:1.2rem;}
}
@media (prefers-reduced-motion:reduce){
  .live-pill[data-state="live"] .live-dot{animation:none;}
  .list-item.just-in{animation:none; background:color-mix(in srgb, var(--accent) 10%, transparent);}
}

/* =========================================================================
   Mobile
   Everything below is inside a media query, so desktop is byte-for-byte
   unchanged. Written after an audit at 375px rather than from assumptions -
   these are the things that were actually wrong:

     * The organization header squashed its own title to 18px wide, because
       the avatar, the text and the "Add monitor" button were fighting over
       one flex row.
     * The stat row collapsed to a single column, so five tiles became a
       column of five screens' worth of scrolling.
     * The tab strips scroll sideways with nothing to say so.
     * Tap targets sat at 28-38px against a 44px minimum.
     * Form inputs below 16px make iOS Safari zoom the whole page on focus.
   ========================================================================= */

@media (max-width:640px){

  /* --- shell --------------------------------------------------------- */
  .container, .admin-wrap, .inbox-wrap, .settings-shell, .docs-shell{
    padding-left:15px; padding-right:15px;
  }
  .settings-shell{padding-top:26px;}

  /* --- organization header ------------------------------------------- */
  /* Avatar and name on one row, the action full-width underneath. The
     button used to sit in the same row and crush the title. */
  .org-header{
    display:grid;
    grid-template-columns:auto 1fr;
    grid-template-areas:"avatar text" "action action";
    gap:12px 14px; padding:16px;
  }
  .org-avatar{grid-area:avatar;}
  .org-header-text{grid-area:text; min-width:0;}
  .org-header > .btn{grid-area:action; width:100%; justify-content:center;}
  .org-header-text h1{font-size:1.25rem; overflow-wrap:anywhere;}
  .org-header-meta{font-size:.8rem;}

  /* --- stats ---------------------------------------------------------- */
  /* Two up. A single column turned five tiles into a lot of scrolling for
     numbers that are meant to be taken in at a glance. */
  .stat-grid{grid-template-columns:1fr 1fr; gap:8px;}
  .stat-tile{padding:12px 13px;}
  .stat-value{font-size:1.5rem;}
  .stat-label{font-size:.65rem; letter-spacing:.07em;}

  /* --- horizontal scrollers ------------------------------------------ */
  /* These legitimately scroll sideways; the fade says so, and the padding
     stops the last item sitting flush against the edge. */
  .org-tabs, .settings-nav, .alias-filter, .monitor-filters{
    -webkit-overflow-scrolling:touch;
    scroll-snap-type:x proximity;
    mask-image:linear-gradient(90deg, #000 calc(100% - 26px), transparent);
    -webkit-mask-image:linear-gradient(90deg, #000 calc(100% - 26px), transparent);
    padding-right:26px;
  }
  .org-tab, .settings-nav button, .filter-chip{scroll-snap-align:start;}
  .monitor-filters{overflow-x:auto; flex-wrap:nowrap;}

  /* --- monitors ------------------------------------------------------- */
  .monitor-card{padding:15px;}
  .monitor-card-head{flex-direction:column; align-items:flex-start; gap:11px;}
  .monitor-actions{width:100%; justify-content:flex-start; flex-wrap:wrap;}
  .monitor-identity{width:100%;}
  .monitor-url{overflow-wrap:anywhere;}
  .monitor-metrics{grid-template-columns:1fr 1fr;}
  .monitor-toolbar{flex-direction:column; align-items:stretch;}
  .monitor-search{min-width:0;}
  .monitor-meta{justify-content:flex-start;}

  /* --- settings ------------------------------------------------------- */
  .row{flex-direction:column; align-items:flex-start; gap:10px;}
  .row > .btn, .row > button, .row > a.btn{width:100%; justify-content:center;}
  .field-grid, .org-settings-grid{grid-template-columns:1fr;}
  .avatar-row{gap:14px;}

  /* --- modals --------------------------------------------------------- */
  /* Full-bleed at the bottom of the screen, which is where a thumb is. */
  .modal-backdrop{padding:0; align-items:flex-end;}
  .modal, .modal.modal-wide{
    max-width:100%; width:100%; max-height:92vh;
    border-radius:16px 16px 0 0; padding:20px 18px calc(20px + env(safe-area-inset-bottom));
  }
  .modal-foot{flex-direction:column-reverse; gap:8px;}
  .modal-foot .btn{width:100%; justify-content:center;}
  .from-picker, .perm-picker{grid-template-columns:1fr;}

  /* --- admin ---------------------------------------------------------- */
  .admin-head{flex-direction:column; align-items:stretch;}
  .lookup-row{flex-direction:column;}
  .lookup-row .btn{width:100%; justify-content:center;}
  .grant-row{flex-direction:column; align-items:stretch;}
  .grant-row .btn{width:100%; justify-content:center;}
  .list-item, .admin-row, .tp-row, .maint-row, .team-row, .holder-row{
    flex-direction:column; align-items:flex-start; gap:10px;
  }
  .list-item .btn, .admin-row .btn, .tp-row .btn{width:100%; justify-content:center;}
  .tp-actions{width:100%;}
  .tp-plan-btn{flex:1; min-width:72px;}
  .admin-actions-row .btn{flex:1 1 auto; justify-content:center;}

  /* --- mail ----------------------------------------------------------- */
  .thread-list{max-height:none;}
  .thread-detail{padding:16px;}

  /* --- first run and plans -------------------------------------------- */
  .first-run{padding:20px;}
  .first-run-head h2{font-size:1.15rem;}
  .plan-grid{grid-template-columns:1fr;}

  /* --- docs ------------------------------------------------------------ */
  .docs-nav{grid-template-columns:1fr;}
  .doc-article{padding:18px;}
  /* A table that cannot shrink gets its own scroller rather than pushing
     the whole page sideways. */
  .doc-table{display:block; overflow-x:auto; white-space:nowrap;}
  .doc-table td:first-child{white-space:normal;}
}

/* --- iOS zoom-on-focus -------------------------------------------------
   Safari zooms the entire page when a focused input has a font smaller than
   16px, which then leaves the layout scrolled sideways. 16px prevents it. */
@media (max-width:820px){
  input, select, textarea{font-size:16px !important;}
}

/* --- touch targets -----------------------------------------------------
   Keyed on the pointer being coarse rather than on width, so a small window
   on a desktop keeps its compact controls and an actual touchscreen gets
   thumb-sized ones. */
@media (pointer:coarse){
  .tb-link, .tb-icon-link, .tb-account, .tb-search,
  .org-tab, .settings-nav button, .filter-chip, .auth-tab,
  .btn, .pause-btn, .check-now-btn, .delete-btn, .alias-filter button,
  .back-link, .tp-plan-btn, .modal-close{
    min-height:44px;
  }
  .btn, .tb-link, .org-tab{display:inline-flex; align-items:center; justify-content:center;}
  .pause-btn, .check-now-btn, .delete-btn{padding-left:14px; padding-right:14px;}
  .tb-icon-link{width:44px; height:44px;}
  .tb-avatar{width:32px; height:32px;}
  /* Menu items are the one place a taller row is worse - it makes the menu
     taller than the screen - so they get the minimum and no more. */
  .tb-menu-item{min-height:44px;}
}

/* =========================================================================
   Liquid glass
   =========================================================================
   Three things make this read as glass rather than as "opacity turned down":

     1. A brighter 1px edge along the top, where light would catch a bevel.
        This does most of the work. Translucency on its own looks like a bug.
     2. Something behind it worth refracting - hence the ambient wash on the
        body. Blur over a flat colour is just a flat colour.
     3. Restraint. Blur is applied to the LARGE surfaces only.

   That last point is the one that separates this from the usual attempt.
   Blurring every card, tile and chip does three bad things: it stacks
   backdrop-filters (each one samples the composited layers beneath, so ten
   panels is ten passes and a phone drops frames); it double-blurs anything
   nested, which looks like a smear rather than glass; and it removes the
   depth hierarchy, because if everything floats then nothing does.

   So: big panels get real blur. Small tiles inside them get the tint and the
   edge but no blur, which is visually consistent and costs nothing.
   ========================================================================= */

/* Something for the glass to refract. Fixed so it does not slide under
   scrolling content and betray the illusion. */
body{
  background-image:var(--body-gradient, none);
  background-attachment:fixed;
  background-repeat:no-repeat;
  background-size:cover;
}

/* ---- the blurred surfaces -------------------------------------------------
   Deliberately a short list. These are the panels large enough that a blurred
   backdrop reads as material rather than as noise. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .app-topbar,
  .topbar,
  .add-monitor-card,
  .team-card,
  .admin-section,
  .billing-card,
  .bill-hero,
  .first-run,
  .tester-panel,
  .empty-state-rich,
  .org-header,
  .modal,
  .tb-menu,
  .docs-nav,
  .doc-article{
    background-color:var(--glass-bg);
    -webkit-backdrop-filter:var(--glass-blur);
    backdrop-filter:var(--glass-blur);
    box-shadow:var(--glass-shadow);
  }

  /* Nested glass is the classic mistake: a blurred panel inside a blurred
     panel samples an already-blurred backdrop and turns to mush. These sit
     inside the panels above, so they get the look without a second pass. */
  .team-card .list-item,
  .admin-section .list-item,
  .doc-article .doc-table,
  .modal .org-choice{
    -webkit-backdrop-filter:none;
    backdrop-filter:none;
  }
}

/* The specular edge. A pseudo-element rather than a border, so it can be a
   gradient that fades out toward the sides - a real bevel is brightest where
   it faces the light, not uniformly lit. */
.app-topbar::after,
.topbar::after,
.add-monitor-card::before,
.team-card::before,
.admin-section::before,
.billing-card::before,
.bill-hero::before,
.first-run::before,
.tester-panel::before,
.empty-state-rich::before,
.org-header::before,
.modal::before,
.tb-menu::before{
  content:'';
  position:absolute;
  inset:0 0 auto 0;
  height:1px;
  background:linear-gradient(90deg, transparent, var(--glass-edge), transparent);
  pointer-events:none;
  border-radius:inherit;
}

/* Those pseudo-elements need a positioned parent, and must not clip content
   that is meant to overflow (the account menu, tooltips). */
.add-monitor-card,
.team-card,
.admin-section,
.billing-card,
.bill-hero,
.first-run,
.tester-panel,
.empty-state-rich,
.org-header,
.modal,
.tb-menu,
.app-topbar,
.topbar{
  position:relative;
}

/* ---- small surfaces: tint and edge, no blur ---------------------------- */
.stat-tile,
.bill-stat,
.monitor-card,
.plan-card,
.check-card,
.es-item,
.why-item,
.deliv-domain,
.tester-plan{
  background-color:var(--glass-bg);
  border-color:color-mix(in srgb, var(--glass-edge) 34%, var(--border));
}

/* A light top edge on these too, drawn with a gradient border-image rather
   than a pseudo-element, because several of them already use ::before. */
.stat-tile,
.monitor-card,
.plan-card{
  background-image:linear-gradient(180deg, color-mix(in srgb, var(--glass-edge) 12%, transparent), transparent 42%);
}

/* Hover lifts the panel toward the light rather than just changing colour. */
.monitor-card{transition:transform .16s ease, border-color .16s ease, box-shadow .16s ease;}
.monitor-card:hover{
  transform:translateY(-1px);
  box-shadow:var(--glass-shadow);
}

/* ---- honesty about legibility -------------------------------------------
   Glass costs contrast. Where text sits directly on a translucent panel over
   a busy gradient, it needs help - so the two palettes with the strongest
   background washes get slightly more opaque panels. Looking good is not
   worth being hard to read. */
:root[data-theme="glass"] .modal,
:root[data-theme="aurora"] .modal,
:root[data-theme="glass"] .add-monitor-card,
:root[data-theme="aurora"] .add-monitor-card{
  background-color:color-mix(in srgb, var(--glass-bg) 60%, var(--bg));
}

/* ---- fallbacks ----------------------------------------------------------- */

/* No backdrop-filter (older Firefox, some in-app browsers): opaque surfaces,
   so the app looks plain rather than looking broken with unreadable text
   floating over a gradient. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-topbar, .topbar, .add-monitor-card, .team-card, .admin-section, .billing-card,
  .bill-hero, .first-run, .tester-panel, .empty-state-rich, .org-header,
  .modal, .tb-menu, .stat-tile, .bill-stat, .monitor-card, .plan-card,
  .check-card, .es-item, .why-item, .deliv-domain, .tester-plan{
    background-color:var(--surface);
  }
}

/* Somebody who has asked their OS to reduce transparency has usually done so
   because translucency makes text hard for them to read. Honour it. */
@media (prefers-reduced-transparency: reduce) {
  .app-topbar, .topbar, .add-monitor-card, .team-card, .admin-section, .billing-card,
  .bill-hero, .first-run, .tester-panel, .empty-state-rich, .org-header,
  .modal, .tb-menu, .stat-tile, .bill-stat, .monitor-card, .plan-card,
  .check-card, .es-item, .why-item, .deliv-domain, .tester-plan{
    background-color:var(--surface);
    -webkit-backdrop-filter:none;
    backdrop-filter:none;
    background-image:none;
  }
  body{background-image:none;}
}

/* Blur is the most expensive thing on this page and a phone has the least to
   spend. Below 640px only the two surfaces that overlap scrolling content -
   where the effect is actually visible - keep it. */
@media (max-width:640px){
  .add-monitor-card, .team-card, .admin-section, .billing-card, .bill-hero,
  .first-run, .tester-panel, .empty-state-rich, .org-header, .docs-nav,
  .doc-article{
    -webkit-backdrop-filter:none;
    backdrop-filter:none;
    background-color:color-mix(in srgb, var(--glass-bg) 70%, var(--surface));
  }
  body{background-attachment:scroll;}
}

/* A real switch, not a checkbox with a label. Used for settings where the
   consequence is immediate - the state IS the setting, so it should look like
   something you flip rather than something you tick and then save. */
.switch{position:relative; display:inline-flex; flex:none; cursor:pointer;}
.switch input{position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer;}
.switch-track{
  display:block; width:46px; height:27px; border-radius:99px;
  background:var(--surface-2, var(--border)); border:1px solid var(--border);
  transition:background .18s ease, border-color .18s ease;
}
.switch-knob{
  display:block; width:19px; height:19px; margin:3px; border-radius:50%;
  background:var(--text-faint);
  transition:transform .18s cubic-bezier(.4,0,.2,1), background .18s ease;
}
.switch input:checked + .switch-track{
  background:color-mix(in srgb, var(--accent) 32%, transparent);
  border-color:var(--accent);
}
.switch input:checked + .switch-track .switch-knob{
  transform:translateX(19px); background:var(--accent);
}
.switch input:focus-visible + .switch-track{
  outline:2px solid var(--accent); outline-offset:2px;
}
.switch input:disabled + .switch-track{opacity:.5; cursor:not-allowed;}
@media (pointer:coarse){
  .switch-track{width:52px; height:31px;}
  .switch-knob{width:23px; height:23px;}
  .switch input:checked + .switch-track .switch-knob{transform:translateX(21px);}
}
@media (prefers-reduced-motion: reduce){
  .switch-track, .switch-knob{transition:none;}
}

/* Organization roles ------------------------------------------------------ */
.my-alerts{
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:14px 16px; border-radius:12px; margin-bottom:16px;
  background-color:var(--glass-bg, var(--surface-2));
  border:1px solid var(--border);
  background-image:linear-gradient(180deg, color-mix(in srgb, var(--glass-edge, #fff) 10%, transparent), transparent 50%);
}
.my-alerts[hidden]{display:none;}
.my-alerts-text{display:grid; gap:3px; min-width:0;}
.my-alerts-text strong{font-size:.88rem;}
.my-alerts-text span{font-size:.8rem; line-height:1.55; color:var(--text-faint);}

.role-form{
  display:grid; gap:16px; padding:18px; border-radius:12px; margin-bottom:16px;
  background:var(--bg); border:1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
}
.role-form[hidden]{display:none;}
.role-split{display:grid; grid-template-columns:1fr 1fr; gap:22px;}
.role-checks{display:grid; gap:8px; margin-top:9px;}
.role-check{font-size:.83rem; line-height:1.45;}

.role-card{
  padding:16px 17px; border-radius:12px; margin-bottom:11px;
  background-color:var(--glass-bg, var(--surface-2));
  border:1px solid var(--border);
}
.role-card-head{display:flex; align-items:flex-start; justify-content:space-between; gap:14px; margin-bottom:11px;}
.role-card-head h3{margin:0; font-size:.98rem; letter-spacing:-.01em;}
.role-card-head .hint{margin:3px 0 0;}
.role-tags{display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px;}
/* Alert subscriptions are the operative part of a role, so they read
   differently from the permissions beside them. */
.tag-alert{
  background:color-mix(in srgb, var(--accent) 15%, transparent);
  border-color:color-mix(in srgb, var(--accent) 38%, var(--border));
  color:var(--accent);
}
.role-holders{display:flex; flex-wrap:wrap; gap:7px; align-items:center; margin-bottom:11px;}
.holder-chip{
  display:inline-flex; align-items:center; gap:7px;
  font-size:.79rem; padding:4px 6px 4px 11px; border-radius:999px;
  background:var(--bg); border:1px solid var(--border);
}
.holder-chip.is-muted{opacity:.6;}
.holder-chip em{
  font-style:normal; font-size:.66rem; text-transform:uppercase; letter-spacing:.05em;
  color:var(--warn);
}
.holder-chip button{
  background:none; border:none; cursor:pointer; color:var(--text-faint);
  font-size:1rem; line-height:1; padding:0 4px;
}
.holder-chip button:hover{color:var(--danger);}
.role-assign{margin:0;}

@media (max-width:640px){
  .role-split{grid-template-columns:1fr; gap:16px;}
  .role-card-head{flex-direction:column;}
  .my-alerts{flex-direction:row; align-items:center;}
}

/* =========================================================================
   Sign-up wizard
   ========================================================================= */

.signup-wizard{display:block;}

/* ---- progress ---- */
.wiz-rail{
  display:flex; justify-content:space-between; align-items:flex-start;
  list-style:none; margin:0 0 10px; padding:0; gap:4px;
}
.wiz-dot{display:flex; flex-direction:column; align-items:center; gap:6px; flex:1; min-width:0;}
.wiz-dot span{
  display:flex; align-items:center; justify-content:center;
  width:26px; height:26px; border-radius:50%;
  font-size:.74rem; font-weight:800;
  background:var(--glass-bg, var(--surface-2)); color:var(--text-faint);
  border:1px solid var(--border);
  transition:background .25s ease, color .25s ease, border-color .25s ease, transform .25s ease;
}
.wiz-dot em{
  font-style:normal; font-size:.66rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color:var(--text-faint);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%;
  transition:color .25s ease;
}
.wiz-dot.is-current span{
  background:var(--accent); color:var(--bg);
  border-color:var(--accent); transform:scale(1.08);
}
.wiz-dot.is-current em{color:var(--accent);}
.wiz-dot.is-done span{
  background:color-mix(in srgb, var(--accent) 22%, transparent);
  color:var(--accent); border-color:color-mix(in srgb, var(--accent) 45%, var(--border));
}
/* A tick rather than the number, once a step is behind you. */
.wiz-dot.is-done span::after{content:'✓'; font-size:.8rem;}
.wiz-dot.is-done span{color:transparent;}
.wiz-dot.is-done span::after{color:var(--accent);}

.wiz-track{
  height:3px; border-radius:99px; background:var(--border);
  overflow:hidden; margin-bottom:24px;
}
.wiz-fill{
  height:100%; width:0; border-radius:99px;
  background:linear-gradient(90deg, var(--accent-dim), var(--accent));
  transition:width .38s cubic-bezier(.4,0,.2,1);
}

/* ---- the sliding stage ----
   Both panels exist together during the swap so they can cross-fade. The
   height is locked by JS for the duration, otherwise the card snaps to the new
   panel's height before the slide finishes and the whole thing jumps. */
.wiz-stage{position:relative; transition:height .32s cubic-bezier(.4,0,.2,1);}
.wiz-step{
  display:grid; gap:16px;
  transition:opacity .28s ease, transform .32s cubic-bezier(.4,0,.2,1);
}
.wiz-step[hidden]{display:none;}
.wiz-step.is-active{opacity:1; transform:none; position:relative;}
/* The two panels overlap mid-transition, so the outgoing one is taken out of
   the layout to stop it pushing the incoming one down the page. */
.wiz-step.is-leaving-left,
.wiz-step.is-leaving-right{
  position:absolute; inset:0 0 auto 0; opacity:0; pointer-events:none;
}
.wiz-step.is-leaving-left{transform:translateX(-22px);}
.wiz-step.is-leaving-right{transform:translateX(22px);}
.wiz-step.is-entering-right{opacity:0; transform:translateX(22px);}
.wiz-step.is-entering-left{opacity:0; transform:translateX(-22px);}

.wiz-title{margin:0; font-size:1.22rem; letter-spacing:-.02em;}
.wiz-sub{margin:0; font-size:.87rem; line-height:1.65; color:var(--text-dim);}
.wiz-hint{margin:0; font-size:.82rem; color:var(--text-faint); text-align:center;}
.wiz-actions{display:flex; gap:10px; margin-top:6px;}
.wiz-actions .btn{flex:1; justify-content:center;}
.wiz-actions .btn-block{flex:1 1 100%;}

/* ---- step 1: the two choices, as glass cards ---- */
.wiz-choices{display:grid; grid-template-columns:1fr 1fr; gap:11px;}
.wiz-choice{
  display:grid; gap:5px; justify-items:start; text-align:left; cursor:pointer;
  padding:15px 15px 16px; border-radius:13px; font-family:inherit; color:var(--text);
  background-color:var(--glass-bg, var(--surface-2));
  border:1px solid var(--border);
  background-image:linear-gradient(180deg, color-mix(in srgb, var(--glass-edge, #fff) 10%, transparent), transparent 45%);
  transition:border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.wiz-choice:hover{transform:translateY(-2px);}
.wiz-choice.is-active{
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent), var(--glass-shadow, 0 10px 24px rgba(0,0,0,.3));
}
.wiz-choice-icon{
  display:flex; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:10px; margin-bottom:4px;
  background:color-mix(in srgb, var(--accent) 14%, transparent); color:var(--accent);
}
.wiz-choice-icon svg{width:19px; height:19px;}
.wiz-choice strong{font-size:.92rem;}
.wiz-choice em{font-style:normal; font-size:.75rem; color:var(--text-faint); line-height:1.5;}

/* ---- VAT result ---- */
.vat-result{
  display:grid; gap:3px; padding:12px 14px; border-radius:11px; margin-top:4px;
  border:1px solid var(--border); background:var(--glass-bg, var(--surface-2));
  animation:vatIn .22s ease-out;
}
@keyframes vatIn{from{opacity:0; transform:translateY(-4px);} to{opacity:1; transform:none;}}
.vat-result[hidden]{display:none;}
.vat-result strong{font-size:.85rem;}
.vat-result span{font-size:.78rem; line-height:1.55; color:var(--text-faint);}
.vat-result.is-checking{color:var(--text-faint); font-size:.83rem;}
.vat-result.is-verified{border-color:color-mix(in srgb, var(--accent) 45%, var(--border));}
.vat-result.is-verified strong{color:var(--accent);}
.vat-result.is-verified strong::before{content:'✓ ';}
.vat-result.is-plausible{border-color:color-mix(in srgb, var(--warn) 38%, var(--border));}
.vat-result.is-plausible strong{color:var(--warn);}
.vat-result.is-bad{border-color:color-mix(in srgb, var(--danger) 45%, var(--border));}
.vat-result.is-bad strong{color:var(--danger);}

/* ---- step 3: one box per digit ----
   A single field with letter-spacing looks tidier and behaves worse: the caret
   hides between characters, backspace is ambiguous, and a pasted code does not
   distribute. Six boxes fix all three. */
.code-boxes{display:flex; gap:8px; justify-content:space-between;}
.code-boxes input{
  flex:1; min-width:0; aspect-ratio:1/1.15; max-height:60px;
  text-align:center; font-size:1.4rem; font-weight:700;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  border-radius:11px; padding:0;
  background-color:var(--glass-bg, var(--bg));
  border:1px solid var(--border); color:var(--text);
  transition:border-color .14s ease, box-shadow .14s ease, transform .14s ease;
}
.code-boxes input:focus{
  outline:none; border-color:var(--accent); transform:translateY(-1px);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}
.code-boxes input:not(:placeholder-shown){border-color:color-mix(in srgb, var(--accent) 42%, var(--border));}
.code-boxes.is-wrong{animation:codeShake .4s;}
@keyframes codeShake{
  0%,100%{transform:none;} 20%{transform:translateX(-7px);} 40%{transform:translateX(7px);}
  60%{transform:translateX(-4px);} 80%{transform:translateX(4px);}
}
.code-boxes.is-verified input{
  border-color:var(--accent);
  box-shadow:0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* ---- step 4 ---- */
.pw-meter{display:grid; gap:5px; margin-top:2px;}
.pw-meter[hidden]{display:none;}
.pw-meter i{
  display:block; height:3px; border-radius:99px; background:var(--border);
  position:relative; overflow:hidden;
}
.pw-meter i::after{
  content:''; position:absolute; inset:0 auto 0 0; border-radius:99px;
  transition:width .25s ease, background .25s ease;
}
.pw-meter em{font-style:normal; font-size:.74rem; color:var(--text-faint);}
.pw-meter[data-score="0"] i::after{width:12%; background:var(--danger);}
.pw-meter[data-score="1"] i::after{width:32%; background:var(--danger);}
.pw-meter[data-score="2"] i::after{width:58%; background:var(--warn);}
.pw-meter[data-score="3"] i::after{width:80%; background:var(--accent);}
.pw-meter[data-score="4"] i::after{width:100%; background:var(--accent);}

.remember-panel{
  padding:14px 15px; border-radius:12px;
  background-color:var(--glass-bg, var(--surface-2));
  border:1px solid var(--border);
  background-image:linear-gradient(180deg, color-mix(in srgb, var(--glass-edge, #fff) 10%, transparent), transparent 50%);
}
.wiz-terms{font-size:.84rem;}
.wiz-terms a{color:var(--accent-2); text-decoration:underline;}

.fld-help.is-good{color:var(--accent);}
.fld-help.is-bad{color:var(--warn);}
.form-error.is-good{color:var(--accent);}

/* ---- reduced motion ----
   The slide is decoration. Somebody who has asked for less of it still needs
   the steps to change. */
@media (prefers-reduced-motion: reduce){
  .wiz-step, .wiz-fill, .wiz-stage, .wiz-dot span, .code-boxes input{transition:none !important;}
  .wiz-step.is-entering-right, .wiz-step.is-entering-left{transform:none;}
  .code-boxes.is-wrong{animation:none;}
  .vat-result{animation:none;}
}

/* =========================================================================
   Auth layout on a phone
   The card was 240px wide on a 375px screen - 135px of the display unused,
   which is why the code entry felt cramped and the whole thing looked like a
   desktop page being viewed on a phone. The 40px side padding was written for
   the two-column desktop layout and never revisited.
   ========================================================================= */
@media (max-width:640px){
  /* Three paddings were stacking - .container 15px, .auth-view 12px and
     .auth-panel 18px - so 90px of a 375px screen went on nested gutters and
     the card ended up 240px wide. The panel provides the only gutter now. */
  main.container:has(.auth-view){padding-left:0; padding-right:0;}
  .auth-view{padding:0;}
  .auth-shell{max-width:none; border-radius:16px;}
  .auth-panel{padding:26px 18px 28px;}
  .auth-card{width:100%;}
  .wiz-title{font-size:1.12rem;}
  .wiz-choices{grid-template-columns:1fr; gap:9px;}
  .wiz-choice{grid-template-columns:auto 1fr; align-items:center; gap:4px 13px; padding:13px 14px;}
  .wiz-choice-icon{grid-row:span 2; margin:0;}
  .wiz-actions{flex-direction:column-reverse;}
  .wiz-actions .btn{width:100%;}
  .wiz-dot em{display:none;}
  .wiz-dot.is-current em{display:block;}
  .code-boxes{gap:6px;}
  .code-boxes input{font-size:1.25rem; max-height:54px;}
}

/* Short screens - a landscape phone, or a small window - have no room for the
   brand column or generous padding. */
@media (max-height:560px){
  .auth-view{align-items:flex-start; padding-top:12px; padding-bottom:12px;}
  .auth-panel{padding-top:18px; padding-bottom:18px;}
  .wiz-rail{margin-bottom:6px;}
  .wiz-track{margin-bottom:16px;}
}

/* ==========================================================================
   Client pages: SLA, Site Audit, portal, contacts
   ========================================================================== */

/* There was never a base rule for this. Every <p class="hint"> outside a
   .card-head-row or .role-card-head was rendering at full body weight and
   colour, which is the opposite of what a hint is for. */
.hint{font-size:.82rem; line-height:1.62; color:var(--text-faint);}

/* Status badges. The client page has always emitted .badge-up / .badge-down
   and there was no rule for either, so they came out as plain text. */
.badge{
  display:inline-block; padding:3px 10px; border-radius:999px;
  font-size:.73rem; font-weight:700; letter-spacing:.02em; text-transform:capitalize;
  border:1px solid transparent;
}
.badge-up, .badge-valid{background:color-mix(in srgb, var(--accent) 15%, transparent); color:var(--accent); border-color:color-mix(in srgb, var(--accent) 32%, transparent);}
.badge-down, .badge-expired, .badge-listed{background:color-mix(in srgb, var(--danger) 15%, transparent); color:var(--danger); border-color:color-mix(in srgb, var(--danger) 32%, transparent);}
.badge-degraded, .badge-expiring_soon, .badge-changed{background:color-mix(in srgb, var(--warn) 15%, transparent); color:var(--warn); border-color:color-mix(in srgb, var(--warn) 32%, transparent);}
.badge-unknown, .badge-error, .badge-unavailable{background:var(--surface); color:var(--text-faint); border-color:var(--border);}

.client-head{align-items:flex-start;}
.client-identity{display:flex; align-items:flex-start; gap:13px; min-width:0;}
.client-identity h1{margin:0;}
.client-identity .hint{margin:3px 0 0;}
.client-swatch{
  width:12px; align-self:stretch; min-height:44px; border-radius:6px; flex:none;
  background:var(--accent); box-shadow:0 0 14px -3px currentColor;
}

.sub-head{font-size:.9rem; margin:22px 0 6px; letter-spacing:-.01em;}
.mini-select{
  background:var(--surface); color:var(--text); border:1px solid var(--border);
  border-radius:9px; padding:7px 11px; font-size:.82rem; font-family:inherit;
}
.mini-select:focus{outline:none; border-color:var(--accent);}

/* A wide table must scroll inside its own box. Letting it push the page
   sideways breaks every other column on the screen to show one extra one. */
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch;}
.report-table td.cell-ok{color:var(--accent); font-weight:600;}
.report-table td.cell-bad{color:var(--danger); font-weight:600;}

/* ---------------------------------------------------------------- SLA --- */
.sla-headline{
  display:flex; align-items:center; justify-content:space-between; gap:18px; flex-wrap:wrap;
  padding:15px 17px; border-radius:12px; margin-bottom:16px;
  border:1px solid var(--border); background:var(--surface);
}
.sla-headline strong{display:block; font-size:1.05rem; letter-spacing:-.01em;}
.sla-label{display:block; font-size:.7rem; text-transform:uppercase; letter-spacing:.07em; color:var(--text-faint); font-weight:700; margin-bottom:2px;}
.sla-ok{border-color:color-mix(in srgb, var(--accent) 35%, var(--border)); background:color-mix(in srgb, var(--accent) 7%, var(--surface));}
.sla-ok strong{color:var(--accent);}
.sla-bad{border-color:color-mix(in srgb, var(--danger) 35%, var(--border)); background:color-mix(in srgb, var(--danger) 7%, var(--surface));}
.sla-bad strong{color:var(--danger);}
.sla-figures{display:flex; gap:20px; flex-wrap:wrap;}
.sla-figures span{font-size:.78rem; color:var(--text-faint);}
.sla-figures em{display:block; font-style:normal; font-size:1.02rem; font-weight:700; color:var(--text);}
.sla-coverage{margin-top:10px; padding-left:11px; border-left:2px solid var(--warn);}

/* -------------------------------------------------------- Site Audit --- */
.grade-chip{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:30px; height:22px; padding:0 7px; margin-left:7px;
  border-radius:7px; font-size:.74rem; font-weight:800; letter-spacing:.01em; vertical-align:middle;
}
.grade-ok{background:color-mix(in srgb, var(--accent) 17%, transparent); color:var(--accent);}
.grade-warn{background:color-mix(in srgb, var(--warn) 19%, transparent); color:var(--warn);}
.grade-bad{background:color-mix(in srgb, var(--danger) 17%, transparent); color:var(--danger);}

.audit-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  padding:13px 0; border-bottom:1px solid var(--border);
}
.audit-row:last-child{border-bottom:none; padding-bottom:0;}
.audit-row-main{min-width:0; display:grid; gap:2px;}
.audit-row-main .hint{margin:0;}
.audit-row-side{display:flex; align-items:center; gap:10px; flex-wrap:wrap;}
.audit-score{font-size:.82rem; color:var(--text-faint); font-variant-numeric:tabular-nums;}

.finding{padding:13px 0 13px 13px; border-bottom:1px solid var(--border); border-left:2px solid var(--border);}
.finding:last-child{border-bottom:none;}
.finding-fail{border-left-color:var(--danger);}
.finding-warn{border-left-color:var(--warn);}
.finding-pass{border-left-color:color-mix(in srgb, var(--accent) 55%, transparent);}
.finding-skip{border-left-color:var(--border); opacity:.72;}
.finding-head{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;}
.finding-head strong{font-size:.9rem; font-weight:600;}
.finding-state{
  font-size:.65rem; font-weight:800; text-transform:uppercase; letter-spacing:.07em;
  white-space:nowrap; flex:none;
}
.finding-fail .finding-state{color:var(--danger);}
.finding-warn .finding-state{color:var(--warn);}
.finding-pass .finding-state{color:var(--accent);}
.finding-skip .finding-state{color:var(--text-faint);}
.finding-detail{margin:4px 0 0; font-size:.83rem; line-height:1.6; color:var(--text-dim);}
.finding-fix{margin:7px 0 0; font-size:.81rem; line-height:1.62; color:var(--text-faint);}
.finding-fix span{
  display:block; font-size:.65rem; font-weight:800; text-transform:uppercase;
  letter-spacing:.07em; color:var(--text-faint); margin-bottom:2px;
}

/* ------------------------------------------------------------- portal --- */
.portal-link-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  padding:12px 14px; margin:4px 0 12px;
  background:var(--surface); border:1px solid var(--border); border-radius:11px;
}
.portal-link-row code{
  font-size:.8rem; color:var(--text-dim); word-break:break-all; min-width:0;
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.callout{
  margin-top:16px; padding:14px 16px; border-radius:11px;
  border:1px solid var(--border); background:var(--surface); font-size:.83rem; line-height:1.62;
}
.callout strong{display:block; margin-bottom:3px; color:var(--text);}
.callout p{margin:0; color:var(--text-faint);}
.callout-info{border-left:3px solid var(--accent);}

/* ----------------------------------------------------------- contacts --- */
.contact-row{
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  padding:13px 0; border-bottom:1px solid var(--border);
}
.contact-row:last-child{border-bottom:none;}
.contact-who{display:grid; gap:1px; min-width:0; flex:1 1 200px;}
.contact-who .hint{margin:0; font-size:.77rem;}
.contact-check{font-size:.8rem; white-space:nowrap;}

.danger-card{border-color:color-mix(in srgb, var(--danger) 26%, var(--border));}
.danger-card h2{color:var(--danger);}

@media (max-width:640px){
  .client-identity{gap:10px;}
  .client-swatch{width:8px; min-height:38px;}
  .sla-headline{padding:13px 14px;}
  .sla-figures{gap:14px; width:100%;}
  .audit-row-side{width:100%; justify-content:space-between;}
  .contact-row{gap:10px;}
  .contact-who{flex-basis:100%;}
  .portal-link-row code{flex-basis:100%;}
  /* Two full-width destructive buttons stacked is a mis-tap waiting to
     happen; keeping them side by side keeps the safer one distinct. */
  .danger-card .admin-actions-row{display:flex; gap:10px; flex-wrap:wrap;}
  .danger-card .admin-actions-row .btn{flex:1 1 150px;}
}

/* MSP client list rows carry a bit more now: a colour swatch matching the
   client's own branding, and the state that decides whether you click. */
.client-row-id{display:flex; align-items:center; gap:11px; min-width:0;}
.client-row-dot{width:9px; height:34px; border-radius:5px; flex:none;}
.client-row-ok{color:var(--accent); font-weight:600;}
.client-row-warn{color:var(--warn); font-weight:600;}
.client-row-bad{color:var(--danger); font-weight:600;}
.client-archived{opacity:.6;}

/* A client's workspace is a real organization, but not a purchase. Marked so
   ten clients do not read as ten subscriptions in the switcher. */
.client-org-tag{
  display:inline-block; margin-left:7px; padding:1px 7px; border-radius:999px;
  font-size:.62rem; font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  background:color-mix(in srgb, var(--accent) 15%, transparent); color:var(--accent);
  vertical-align:middle;
}
.org-card-client{border-style:dashed;}
.clients-allowance{margin:14px 0 0; padding-top:12px; border-top:1px solid var(--border);}
.clients-allowance.is-full{color:var(--warn);}
.client-head-actions{display:flex; gap:10px; flex-wrap:wrap; align-items:center;}
@media (max-width:640px){
  .client-head-actions{width:100%;}
  .client-head-actions .btn{flex:1 1 140px;}
}

/* ============================================================
   Admin: MSP activation
   ============================================================ */
.msp-box{padding-top:22px; border-top:1px solid var(--border);}
.msp-box h3{font-size:.92rem;}
.msp-quote-box{
  margin-top:12px; padding:14px 16px; border-radius:11px;
  background:var(--surface); border:1px solid var(--border);
}
.msp-quote-amount{font-size:1.4rem; font-weight:800; color:var(--accent);}
.msp-quote-amount span{font-size:.78rem; font-weight:600; color:var(--text-faint); margin-left:6px;}
.msp-quote-breakdown{margin:10px 0 0; padding:0; list-style:none; font-size:.82rem; color:var(--text-dim);}
/* Label left, figure right, with a leader between - the two used to run
   together as "List price£499.00" with no gap at all. */
.msp-quote-breakdown li{
  display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  padding:5px 0; border-bottom:1px solid var(--border);
}
.msp-quote-breakdown li:last-child{border-bottom:none;}
.msp-quote-breakdown li strong{color:var(--text); font-variant-numeric:tabular-nums; white-space:nowrap;}

/* ---- MSP pricing desk (admin) ----
   The calculator and activation flow as a standalone tab: the real order of
   events is a phone call first and a named customer second, so it cannot
   live only inside an organization's detail panel. */
.msp-calc-grid{
  display:flex; flex-wrap:wrap; gap:14px; align-items:flex-end; margin-top:16px;
}
.msp-calc-grid label{
  display:flex; flex-direction:column; gap:6px; flex:1 1 220px;
  font-size:.84rem; color:var(--text-dim); font-weight:600;
}
.msp-calc-grid input, .msp-calc-grid select{
  padding:9px 11px; border:1px solid var(--border); border-radius:9px;
  background:var(--surface-2); color:var(--text); font-family:inherit; font-size:.92rem;
}
.msp-quote-lead{font-size:.86rem; color:var(--text-dim); margin:2px 0 14px;}
.msp-org-list{display:flex; flex-direction:column; gap:8px; margin-top:14px;}
.msp-org-row{
  display:flex; flex-direction:column; gap:3px; text-align:left; width:100%;
  padding:11px 14px; border:1px solid var(--border); border-radius:10px;
  background:var(--surface-2); color:var(--text); cursor:pointer; font-family:inherit;
  transition:border-color .12s ease, background .12s ease;
}
.msp-org-row:hover{border-color:var(--accent-dim);}
.msp-org-row.selected{border-color:var(--accent); background:var(--surface);}
.msp-org-name{font-weight:650; font-size:.95rem;}
.msp-org-meta{font-size:.78rem; color:var(--text-faint);}
.msp-box-ok{border-color:var(--accent-dim);}
.msp-box-ok input[readonly]{
  width:100%; margin-top:6px; padding:9px 11px; border:1px solid var(--border);
  border-radius:9px; background:var(--surface-2); color:var(--text);
  font-family:inherit; font-size:.86rem;
}

/* ---- Prospect check (MSP desk) ----
   Deliberately reads as observations rather than a verdict: these are the
   few things about a prospect that can genuinely be looked up, and the
   caveat line exists so nobody mistakes it for verifying their numbers. */
.msp-optional{font-weight:400; color:var(--text-faint); text-transform:none; letter-spacing:0;}
.msp-verify{
  margin-top:16px; padding:16px 18px; border:1px solid var(--border);
  border-radius:12px; background:var(--surface-2);
}
.msp-verify h4{margin:0 0 12px; font-size:.92rem; font-weight:650;}
.msp-verify-list{list-style:none; margin:0; padding:0; font-size:.85rem;}
.msp-verify-list li{
  display:flex; align-items:baseline; gap:12px; justify-content:space-between;
  padding:7px 0; border-bottom:1px solid var(--border);
}
.msp-verify-list li:last-child{border-bottom:none;}
.verify-label{font-weight:600; white-space:nowrap;}
.verify-detail{color:var(--text-dim); text-align:right;}
.msp-verify-list li.verify-ok .verify-label{color:var(--accent);}
.msp-verify-list li.verify-warn .verify-label{color:var(--warn);}
.msp-verify-list li.verify-bad .verify-label{color:var(--danger);}
.msp-verify-list li.verify-unknown .verify-label{color:var(--text-faint);}
.msp-verify-flags{
  margin:14px 0 0; padding:12px 14px 12px 30px; border-radius:9px;
  background:color-mix(in srgb, var(--warn) 12%, transparent);
  font-size:.84rem; line-height:1.6; color:var(--text);
}
.msp-verify-flags li{margin-bottom:6px;}
.msp-verify-flags li:last-child{margin-bottom:0;}
.msp-verify-caveat{
  margin:12px 0 0; font-size:.78rem; color:var(--text-faint); line-height:1.55;
}

/* Signup-link controls, inside the quote box. A prospect with no account
   cannot be activated, so this is the only way they can buy at all. */
.msp-quote-actions{
  display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end;
  margin-top:16px; padding-top:16px; border-top:1px solid var(--border);
}
.msp-quote-actions label{
  display:flex; flex-direction:column; gap:6px; flex:1 1 180px;
  font-size:.8rem; color:var(--text-dim); font-weight:600;
}
.msp-quote-actions input{
  padding:9px 11px; border:1px solid var(--border); border-radius:9px;
  background:var(--surface); color:var(--text); font-family:inherit; font-size:.92rem;
}


/* ---- admin: company finance ------------------------------------------- */
.fin-days{display:inline-block; padding:1px 9px; border-radius:999px; border:1px solid currentColor; font-size:.72rem; font-weight:600; line-height:1.6; white-space:nowrap; vertical-align:middle;}
.fin-days.overdue, .fin-days.soon{color:var(--danger);}
.fin-days.near{color:var(--warn);}
.fin-days.far{color:var(--accent);}
.fin-days.none{color:var(--text-faint);}
.fin-pay{color:var(--text-dim);}
.fin-pay.needs{color:var(--warn); font-weight:600;}
.fin-negative{color:var(--danger);}
.fin-inactive{opacity:.55;}
.fin-warn{margin:0 0 14px; padding:12px 14px; border-radius:12px; font-size:.88rem; border:1px solid color-mix(in srgb, var(--warn) 45%, transparent); background:color-mix(in srgb, var(--warn) 10%, transparent);}
.fin-leads{display:flex; flex-wrap:wrap; gap:8px;}
.fin-leads label{display:inline-flex; align-items:center; gap:6px; padding:5px 12px; border:1px solid var(--border); border-radius:999px; font-size:.82rem; cursor:pointer;}
.fin-toggle{display:flex; align-items:center; gap:9px; margin-bottom:16px; font-weight:600; cursor:pointer;}
.fin-toggle-inline{margin:26px 0 0; font-weight:500;}
.fin-subhead{margin:24px 0 8px; font-size:.9rem; font-weight:600; color:var(--text-dim);}
.fin-grid{display:grid; grid-template-columns:1fr 1fr; gap:0 14px;}
@media (max-width:640px){
  .fin-grid{grid-template-columns:1fr;}
  .fin-toggle-inline{margin-top:4px;}
}

/* ---- admin: finance, the locked Telegram group ------------------------- */
.compose-field > label.fin-toggle{display:flex; align-items:center; gap:9px; text-transform:none; letter-spacing:normal; font-size:.9rem; font-weight:500; color:var(--text);}
.fin-locked{margin:2px 0 10px; font-size:.9rem; color:var(--text-dim);}

/* ---- topbar: the app launcher shared with every Walters Sentinel service ---- */
.tb-left{position:relative;}
.tb-apps{display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px; flex:none; border-radius:9px; border:1px solid transparent; background:none; color:var(--text-dim); cursor:pointer;}
.tb-apps:hover, .tb-apps[aria-expanded="true"]{background:var(--surface-2); color:var(--text); border-color:var(--border);}
.tb-apps-pop{position:absolute; left:0; top:calc(100% + 10px); z-index:70; width:320px; max-width:calc(100vw - 24px); background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:10px; box-shadow:0 22px 50px -18px rgba(0,0,0,.6);}
.tb-apps-title{margin:4px 6px 8px; font-size:.7rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-faint);}
.tb-apps-grid{display:grid; grid-template-columns:repeat(3, 1fr); gap:4px;}
.tb-app{display:flex; flex-direction:column; align-items:center; gap:6px; padding:10px 4px; border-radius:10px; color:var(--text); text-decoration:none; font-size:.76rem; font-weight:600; text-align:center;}
.tb-app:hover{background:var(--surface-2);}
.tb-app-icon{display:flex; align-items:center; justify-content:center; width:38px; height:38px; border-radius:10px; color:#fff;}
.tb-app-icon.is-logo{overflow:hidden;}
.tb-app-icon.is-logo img{width:100%; height:100%; display:block;}
.tb-apps-foot{display:block; margin-top:8px; padding:9px 6px 2px; border-top:1px solid var(--border); font-size:.82rem; color:var(--accent-2); text-decoration:none;}

/* The company shield is near-black: a hairline and a faint green glow keep
   its outline visible on dark backgrounds without changing the logo. */
img[src*="walterssentinel-shield"]{filter:drop-shadow(0 0 .6px rgba(255,255,255,.75)) drop-shadow(0 0 7px rgba(51,214,166,.28));}
