:root {
  --bg:#f6f7f9;--surface:#fff;--surface-soft:#f8f9fb;--border:#e2e5e9;--border-strong:#d2d7de;
  --text:#272b31;--muted:#6d747e;--faint:#969da7;--primary:#1668ff;--primary-soft:#eaf2ff;
  --success:#188757;--success-soft:#e8f6ef;--warning:#9b6500;--warning-soft:#fff6df;
  --danger:#c63c3c;--danger-soft:#fff0f0;--radius:7px;--shadow:0 1px 2px rgba(24,31,42,.035);
  --sans:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace
}
*{box-sizing:border-box}html{min-width:320px;background:var(--bg)}body{margin:0;color:var(--text);background:var(--bg);font:14px/1.45 var(--sans)}[hidden]{display:none!important}
/* Any plain link is rendered in --primary (blue), so it's underlined by default to read as clickable text
   without relying on color alone -- .button overrides this (buttons aren't text links), and so does anything
   deliberately NOT colored blue (nav bar, breadcrumb, brand), each explicitly below. */
a{color:var(--primary);text-decoration:underline}button,input,textarea{font:inherit}code,pre,.mono{font-family:var(--mono)}.ti{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.topbar{height:58px;padding:0 24px;display:flex;align-items:center;gap:28px;background:var(--surface);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:20}
.brand{display:flex;align-items:center;gap:9px;color:var(--text);font-weight:720;font-size:16px;text-decoration:none}
.brand-mark{width:24px;height:24px;display:grid;place-items:center;border-radius:6px;background:var(--primary);color:#fff}.brand-mark svg{width:17px;height:17px;stroke-width:2}
.main-nav{height:100%;display:flex;align-items:stretch;gap:22px}.main-nav a{display:flex;align-items:center;color:var(--muted);font-weight:550;border-bottom:2px solid transparent;text-decoration:none}
.main-nav a:hover{color:var(--text)}.main-nav a.active{color:var(--primary);border-bottom-color:var(--primary)}.topbar-spacer{flex:1}
.page{width:100%;padding:20px 24px 56px}.page-heading{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:18px}
.page-heading h1{margin:0;font-size:24px;line-height:1.2;letter-spacing:-.02em}.page-heading p{margin:5px 0 0;color:var(--muted)}
/* Used only inside .page-heading (DetailHeading): the parent page's own page-heading <h1> becomes the first
   link here, at the exact same size it had on that page -- the breadcrumb doesn't shrink it down to a small
   trail, it just keeps building sideways at heading size, ending in this page's own name. One continuous
   heading that's also the navigation back up, not a small trail with a separate title bolted on after it. */
.breadcrumb{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px;margin-bottom:0;color:var(--muted);font-size:24px;line-height:1.2;letter-spacing:-.02em}
.breadcrumb a{color:var(--text);font-weight:700;padding:3px 9px;margin-left:-9px;border-radius:7px;text-decoration:none;transition:background-color .15s,color .15s}
.breadcrumb a:hover{background:var(--surface-soft);color:var(--primary);text-decoration:underline}
.breadcrumb a:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.breadcrumb-sep{color:var(--faint);font-size:22px;line-height:1}
.breadcrumb>span:last-child{color:var(--text);font-weight:700;padding-left:5px}
.notice{display:flex;gap:10px;align-items:flex-start;padding:10px 13px;margin-bottom:18px;border:1px solid #eedcae;border-radius:var(--radius);background:var(--warning-soft);color:#75500b}
.notice.danger{background:var(--danger-soft);border-color:#f1caca;color:var(--danger)}.notice-icon{width:22px;height:22px;display:grid;place-items:center;flex:0 0 auto}.notice-icon svg{width:21px;height:21px}
.metrics{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr));gap:12px;margin-bottom:16px}.metric{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow)}
.metric-value{font-size:26px;line-height:1;font-weight:720;letter-spacing:-.025em}.metric-label{margin-top:7px;color:var(--muted);font-size:13px}.metric.connected .metric-value{color:var(--success)}.metric.revoked .metric-value{color:var(--danger)}
.dashboard-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-areas:"status model firmware" "fleet fleet fleet";gap:16px}.dashboard-status{grid-area:status}.dashboard-model{grid-area:model}.dashboard-firmware{grid-area:firmware}.dashboard-fleet{grid-area:fleet}.dashboard-grid .facet-card{height:100%}.facet-card{min-height:170px;padding:17px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow)}.facet-title{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:14px}.facet-title h2{margin:0;font-size:16px}.facet-title>span{color:var(--faint);font-size:11px}.facet-row{margin-top:11px}.facet-row>div:first-child{display:flex;justify-content:space-between;gap:12px;color:var(--muted);font-size:12px}.facet-row strong{color:var(--text)}.facet-track{height:5px;margin-top:5px;overflow:hidden;border-radius:5px;background:var(--surface-soft)}.facet-track span{display:block;height:100%;border-radius:inherit;background:#9daabd}.facet-row.connected .facet-track span{background:var(--success)}.facet-row.revoked .facet-track span{background:var(--danger)}
.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow)}.panel+.panel{margin-top:16px}
.panel-header{min-height:55px;padding:13px 17px;display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid var(--border)}.panel-header h2{margin:0;font-size:16px}.panel-subtitle{color:var(--muted);font-size:12px;font-weight:400;margin-left:6px}
.panel-body{padding:17px}.panel-empty{padding:34px 18px;text-align:center;color:var(--muted)}
.bulk-toolbar{display:flex;align-items:center;gap:12px;padding:10px 17px;border-bottom:1px solid var(--border);background:var(--primary-soft);color:var(--primary);font-size:13px;font-weight:600}.bulk-toolbar-actions{display:flex;gap:8px;margin-left:auto}
.checkbox-cell{width:36px;padding-right:0}
.switch{position:relative;display:inline-block;width:36px;height:20px}.switch input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.switch span{position:absolute;inset:0;background:var(--border-strong);border-radius:999px;transition:background-color .15s}.switch span::before{content:"";position:absolute;left:2px;top:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .15s}
.switch input:checked+span{background:var(--primary)}.switch input:checked+span::before{transform:translateX(16px)}.switch input:disabled+span{opacity:.5;cursor:not-allowed}
.pagination{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;padding:12px 17px;border-bottom:1px solid var(--border)}
.pagination-size{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:12px}.pagination-size select{padding:5px 8px;font-size:12px}
.pagination-pages{display:flex;align-items:center;gap:5px;flex-wrap:wrap}.pagination-pages .button{padding:6px 11px;font-size:13px}
.pagination-page{min-width:30px;padding:5px 8px;border:1px solid transparent;border-radius:6px;background:transparent;color:var(--muted);font:inherit;font-size:13px;cursor:pointer}.pagination-page:hover{background:var(--surface-soft);color:var(--text)}.pagination-page.active{background:var(--primary);color:#fff;font-weight:650}
.pagination-ellipsis{color:var(--faint);padding:0 2px;user-select:none}
.pagination-jump{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:12px}.pagination-jump input{width:64px;padding:5px 8px;border:1px solid var(--border-strong);border-radius:6px;background:var(--surface);color:var(--text);font:inherit;font-size:12px}
@media(max-width:640px){.pagination{justify-content:center}.pagination-jump{width:100%;justify-content:center}}
.toolbar{display:flex;gap:9px;align-items:center;flex-wrap:wrap}.search{position:relative;min-width:270px}.search svg{position:absolute;left:10px;top:50%;width:18px;height:18px;transform:translateY(-50%);color:var(--faint)}
input,textarea,select{border:1px solid var(--border-strong);border-radius:6px;background:var(--surface);color:var(--text);padding:8px 10px;font-family:var(--mono);font-size:13px}
input,textarea{width:100%}.field select{width:100%}
.search input{padding-left:33px;font-family:var(--sans)}input:focus,textarea:focus{outline:0;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}textarea{min-height:100px;resize:vertical}
.filter-group{display:inline-flex;border:1px solid var(--border);border-radius:6px;overflow:hidden}.filter-btn{border:0;border-right:1px solid var(--border);border-radius:0;background:var(--surface);color:var(--muted);padding:7px 11px;cursor:pointer}.filter-btn:last-child{border-right:0}.filter-btn.active{background:var(--primary-soft);color:var(--primary)}
.toolbar select{font:inherit}
.table-wrap{overflow-x:auto}table{width:100%;border-collapse:collapse}th{padding:10px 14px;text-align:left;color:var(--muted);background:var(--surface-soft);border-bottom:1px solid var(--border);font-size:12px;font-weight:650;white-space:nowrap}
td{padding:12px 14px;border-bottom:1px solid var(--border);vertical-align:middle}tbody tr:last-child td{border-bottom:0}tbody tr[data-searchable]:hover{background:#fafcff}
.device-name,.link-strong{color:var(--primary);font-family:var(--mono);font-weight:650;text-decoration:underline}.secondary{color:var(--muted);font-size:12px}
/* width:fit-content pins this to its own content: as the first child of .health-copy (a lone flex item inside
   .health-line, sized by its widest line -- the detail sentence below it), the pill would otherwise stretch
   to fill that same computed width instead of staying pill-shaped. */
.status-pill{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;width:fit-content;border-radius:999px;color:var(--muted);background:#eef0f3;font-size:12px;font-weight:620;white-space:nowrap}
.status-pill.connected,.status-pill.ok{color:var(--success);background:var(--success-soft)}.status-pill.revoked,.status-pill.danger,.status-pill.error{color:var(--danger);background:var(--danger-soft)}.status-pill.warn,.status-pill.pending{color:var(--warning);background:var(--warning-soft)}
.status-dot{width:7px;height:7px;border-radius:50%;background:#a5abb3;display:inline-block}.status-dot.online,.connected .status-dot,.ok .status-dot{background:var(--success)}.revoked .status-dot,.danger .status-dot,.error .status-dot{background:var(--danger)}.warn .status-dot,.pending .status-dot{background:#d18b00}
.device-tabs{display:flex;align-items:stretch;gap:4px;margin:0 0 16px;padding:0 8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow-x:auto;scrollbar-width:none}.device-tabs::-webkit-scrollbar{display:none}
.tab-btn{appearance:none;border:0;border-bottom:2px solid transparent;background:none;color:var(--muted);padding:12px 17px 10px;cursor:pointer;white-space:nowrap}.tab-btn:hover{color:var(--text)}.tab-btn.active{color:var(--primary);border-bottom-color:var(--primary);background:var(--primary-soft)}.tab-panel{display:none}.tab-panel.active{display:block}
.device-hero{margin-bottom:16px}
.device-details{padding:22px 26px}.health-line{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;padding-bottom:17px;margin-bottom:17px;border-bottom:1px solid var(--border)}
/* Named class instead of a bare "span" tag: a bare-tag descendant selector here also matched .status-pill and
   .status-dot (both spans), a more specific selector than their own .status-pill{display:inline-flex} rule,
   silently forcing them to display:block -- the cause of the stretched-pill bug. */
.health-detail{display:block;margin-top:5px;color:var(--muted)}
.health-action{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.facts{display:grid;grid-template-columns:repeat(3,minmax(160px,1fr));gap:19px 30px}.fact-label{color:var(--muted);font-size:12px;font-weight:620;margin-bottom:4px}.fact-value{min-height:20px;word-break:break-word}
.details-subhead{display:flex;align-items:baseline;gap:10px;margin:22px 0 14px;padding-top:18px;border-top:1px solid var(--border)}.details-subhead h3{margin:0;font-size:13px;color:var(--muted);font-weight:650;text-transform:uppercase;letter-spacing:.04em}.details-subhead>:nth-child(3){margin-left:auto}
.content-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.content-grid .panel+.panel{margin-top:0}.action-section h3{margin:0 0 4px;font-size:15px}.action-section>p{margin:0 0 17px;color:var(--muted);font-size:13px}
.action-form{padding:14px 0;border-top:1px solid var(--border)}.action-form:first-of-type{border-top:0;padding-top:0}.action-form label{display:block;margin-bottom:6px;color:var(--muted);font-size:12px;font-weight:620}.field-row{display:flex;align-items:flex-end;gap:9px}.field{flex:1;min-width:0}.field+.field,.field+.field-row{margin-top:10px}.field-hint{margin:8px 0 0;color:var(--muted);font-size:12px;line-height:1.5}
.button{border:1px solid var(--primary);border-radius:6px;background:var(--primary);color:white;padding:8px 14px;font-weight:620;cursor:pointer;white-space:nowrap}.button:hover{filter:brightness(1.05)}.button.secondary-btn{background:var(--surface);color:var(--text);border-color:var(--border-strong)}.button.danger-btn{background:var(--danger);border-color:var(--danger)}.button:disabled{cursor:not-allowed;opacity:.48;filter:grayscale(.2)}.button.loading{cursor:wait}.spinner{display:inline-block;width:11px;height:11px;margin-right:6px;border:2px solid rgba(255,255,255,.45);border-top-color:currentColor;border-radius:50%;animation:spin .7s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}
.result{margin-bottom:16px;border-left:3px solid var(--success)}.result.error{border-left-color:var(--danger)}.result-summary{font-size:15px;font-weight:650}.result .panel-body p{color:var(--muted);margin:4px 0 0}.raw-toggle{margin-top:12px}details summary{cursor:pointer;color:var(--primary);font-size:12px;user-select:none}
.danger-zone{margin-top:16px;border:1px solid var(--border);border-radius:10px}.danger-zone summary,details.setup-details>summary{padding:12px 16px;font-size:13px;font-weight:620;color:var(--muted)}.danger-zone summary:hover,details.setup-details>summary:hover{color:var(--text)}.danger-zone[open] summary,details.setup-details[open]>summary{border-bottom:1px solid var(--border)}.danger-zone .panel-body{padding:14px 16px}
pre.json{margin:9px 0 0;padding:12px;max-height:340px;overflow:auto;border:1px solid var(--border);border-radius:6px;background:#f7f8fa;color:#31363d;font-size:12px;white-space:pre-wrap;word-break:break-word}.jk{color:#155ac5}.js{color:#17744e}.jn{color:#9c4f00}.jb{color:#843ac1}
.timeline{padding:0 17px}.timeline-item{display:grid;grid-template-columns:12px minmax(130px,165px) 1fr auto;gap:12px;align-items:start;padding:15px 0;border-bottom:1px solid var(--border)}.timeline-item:last-child{border-bottom:0}.timeline-marker{width:9px;height:9px;margin-top:5px;border-radius:50%;background:#aeb4bd;box-shadow:0 0 0 4px #f1f2f4}.timeline-item.ok .timeline-marker{background:var(--success);box-shadow:0 0 0 4px var(--success-soft)}.timeline-item.error .timeline-marker{background:var(--danger);box-shadow:0 0 0 4px var(--danger-soft)}.timeline-item.pending .timeline-marker{background:#d18b00;box-shadow:0 0 0 4px var(--warning-soft)}
.timeline-time{color:var(--muted);font-size:12px;white-space:nowrap}.timeline-title{font-weight:640}.timeline-summary{margin-top:2px;color:var(--muted);font-size:13px}.kind{color:var(--faint);font-size:11px;text-transform:uppercase;letter-spacing:.04em}.certificate-actions{display:flex;justify-content:flex-end}.inline-form{margin:0}.muted{color:var(--muted)}.nowrap{white-space:nowrap}
/* interaction and finish layer */
:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.eyebrow{margin-bottom:5px;color:var(--primary);font-size:11px;font-weight:750;letter-spacing:.08em;text-transform:uppercase}
.button{display:inline-flex;align-items:center;justify-content:center;gap:6px;text-decoration:none}.button:hover{text-decoration:none}.button .ti{width:16px;height:16px}
.icon-button{width:38px;height:38px;display:grid;place-items:center;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--muted);cursor:pointer}.icon-button svg{width:20px;height:20px}.icon-button:hover{color:var(--text);background:var(--surface-soft)}.moon-icon{display:none}
.device-cell{display:flex;align-items:center;gap:11px}.device-avatar{width:38px;height:38px;display:grid;place-items:center;flex:0 0 auto;border-radius:8px;background:var(--primary-soft);color:var(--primary)}.device-avatar svg{width:22px;height:22px}.clickable-row{cursor:pointer}.clickable-row:focus{background:var(--primary-soft)}.row-arrow{width:19px;height:19px;float:right;margin-left:18px;color:var(--faint);vertical-align:middle}
.tab-btn{display:flex;align-items:center}.tab-icon{width:20px;height:20px;margin-right:7px;color:var(--faint)}.tab-btn.active .tab-icon{color:var(--primary)}.tab-count{display:inline-grid;place-items:center;min-width:20px;height:18px;margin-left:6px;padding:0 5px;border-radius:9px;background:#eef0f3;color:var(--muted);font-size:10px}.tab-btn.active .tab-count{background:#d7e6ff;color:var(--primary)}
.copy-value{display:flex;align-items:center;gap:7px}.copy-value button{padding:2px 5px;border:0;border-radius:4px;background:transparent;color:var(--faint);font-size:10px;cursor:pointer;opacity:0}.copy-value:hover button,.copy-value button:focus{opacity:1}.copy-value button:hover{background:var(--surface-soft);color:var(--primary)}
.copy-cell{display:inline-flex;align-items:center;gap:5px}.copy-icon-btn{display:inline-flex;padding:2px;border:0;border-radius:4px;background:transparent;color:var(--faint);cursor:pointer;opacity:0}.copy-icon-btn .ti{width:13px;height:13px}tr:hover .copy-icon-btn,.copy-icon-btn:focus{opacity:1}.copy-icon-btn:hover{background:var(--surface-soft);color:var(--primary)}
.section-heading{display:flex;align-items:flex-start;gap:12px;margin-bottom:16px}.section-heading h3{margin:1px 0 0}.section-heading p{margin:3px 0 0;color:var(--muted);font-size:13px}.section-icon{width:36px;height:36px;display:grid;place-items:center;flex:0 0 auto;border-radius:50%}.section-icon svg{width:21px;height:21px}.section-icon.safe{background:var(--success-soft);color:var(--success)}.section-icon.risk{background:var(--danger-soft);color:var(--danger)}
.presets{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:8px}.presets span{color:var(--faint);font-size:10px;text-transform:uppercase;letter-spacing:.04em}.presets button{padding:3px 7px;border:1px solid var(--border);border-radius:999px;background:var(--surface-soft);color:var(--muted);font-size:10px;cursor:pointer}.presets button:hover{border-color:var(--primary);color:var(--primary)}
.activity-filters{display:flex;gap:3px;flex-wrap:wrap}.activity-filters button{padding:5px 9px;border:0;border-radius:5px;background:transparent;color:var(--muted);font-size:11px;cursor:pointer}.activity-filters button:hover{background:var(--surface-soft);color:var(--text)}.activity-filters button.active{background:var(--primary-soft);color:var(--primary)}
.dialog-card{display:grid;grid-template-columns:46px minmax(0,1fr);gap:14px;padding:22px;background:var(--surface);color:var(--text)}.dialog-icon{width:42px;height:42px;display:grid;place-items:center;border-radius:50%;background:var(--danger-soft);color:var(--danger)}.dialog-icon svg{width:23px;height:23px}.dialog-copy{min-width:0}.dialog-copy h2{margin:1px 0 6px;font-size:17px}.dialog-copy p{margin:0;color:var(--muted);overflow-wrap:anywhere}.confirmation-identity{margin-top:13px;padding:9px 11px;border:1px solid var(--border);border-radius:6px;background:var(--surface-soft)}.confirmation-identity span{display:block;margin-bottom:4px;color:var(--faint);font-size:10px;font-weight:650;letter-spacing:.045em;text-transform:uppercase}.confirmation-identity code{display:block;color:var(--text);font-size:11px;line-height:1.45;overflow-wrap:anywhere}.confirmation-warning{display:flex;align-items:flex-start;gap:7px;margin-top:11px;color:var(--text);font-size:12px;line-height:1.45}.confirmation-warning svg{width:16px;height:16px;flex:0 0 auto;margin-top:1px;color:var(--danger)}.dialog-actions{grid-column:1/-1;min-width:0;display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:8px}
.toast-region{position:fixed;right:18px;bottom:18px;z-index:50;display:flex;flex-direction:column;gap:8px;pointer-events:none}.toast{min-width:180px;padding:10px 13px;border:1px solid var(--border);border-radius:7px;background:var(--text);color:var(--surface);box-shadow:0 8px 30px rgba(20,25,35,.18);animation:toast-in .2s ease-out}.toast.out{opacity:0;transform:translateY(5px);transition:.2s}@keyframes toast-in{from{opacity:0;transform:translateY(5px)}}
/* RemoteSessionsMenu reuses .org-switch/.user-menu-body/.menu-heading (see OrganizationSwitcher) for the
   trigger and dropdown shell -- only these two rules are specific to its own row content. */
.remote-sessions-menu .user-menu-body{min-width:300px}
.remote-session-item{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:7px 8px}
.remote-session-item+.remote-session-item{border-top:1px solid var(--border)}
.remote-session-copy{display:flex;flex-direction:column;gap:2px;min-width:0}
.remote-session-copy a{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.remote-session-copy .secondary{font-size:11px}
.loading-screen{min-height:220px;display:flex;align-items:center;justify-content:center;gap:10px;color:var(--muted)}.spinner.dark{width:17px;height:17px;margin:0;border-color:var(--border-strong);border-top-color:var(--primary)}
.error-state{max-width:540px;margin:60px auto;padding:38px;text-align:center}.error-state>svg{width:38px;height:38px;color:var(--danger)}.error-state h2{margin:14px 0 5px}.error-state p{margin:0 0 18px;color:var(--muted)}
.modal-backdrop{position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:15px;background:rgba(22,27,34,.5);backdrop-filter:blur(2px)}.modal-card{width:min(520px,calc(100vw - 30px));max-width:100%;max-height:calc(100vh - 30px);overflow:auto;border:1px solid var(--border);border-radius:10px;box-shadow:0 20px 70px rgba(15,20,30,.25)}.modal-card.certificate-confirmation{width:min(620px,calc(100vw - 30px))}
.certificate-history{padding:0 17px}.history-record{display:grid;grid-template-columns:minmax(320px,2fr) minmax(120px,.7fr) minmax(190px,1fr);gap:24px;padding:15px 0;border-bottom:1px solid var(--border)}.history-record:last-child{border-bottom:0}.history-fingerprint{word-break:break-all;font-size:12px}
html[data-theme="dark"]{color-scheme:dark;--bg:#11151a;--surface:#181d24;--surface-soft:#20262e;--border:#2b323c;--border-strong:#3a434f;--text:#edf0f4;--muted:#a2aab5;--faint:#737d89;--primary:#69a3ff;--primary-soft:#1e3353;--success:#55c58c;--success-soft:#163729;--warning:#e4b653;--warning-soft:#3a301b;--danger:#ff7b7b;--danger-soft:#412323;--shadow:0 1px 2px rgba(0,0,0,.2)}html[data-theme="dark"] .sun-icon{display:none}html[data-theme="dark"] .moon-icon{display:block}html[data-theme="dark"] tbody tr[data-searchable]:hover{background:#1c2430}html[data-theme="dark"] pre.json{background:#12171d;color:#e1e5eb}html[data-theme="dark"] .tab-count{background:#2b323c}html[data-theme="dark"] .tab-btn.active .tab-count{background:#294872}html[data-theme="dark"] .toast{background:#edf0f4;color:#181d24}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
@media(max-width:900px){.metrics{grid-template-columns:repeat(2,1fr)}.facts{grid-template-columns:repeat(2,1fr)}.content-grid{grid-template-columns:1fr}.timeline-item{grid-template-columns:12px minmax(110px,140px) 1fr}.timeline-item details{grid-column:3}.activity-filters{width:100%}.panel-header:has(.activity-filters){align-items:flex-start;flex-direction:column}}
@media(max-width:640px){.topbar{padding:0 12px;gap:13px}.brand>span:last-child{display:none}.main-nav{gap:12px}.page{padding:16px 12px 40px}.page-heading{align-items:flex-start;flex-direction:column}.metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.metric{padding:13px}.metric-value{font-size:22px}.toolbar{width:100%}.search{min-width:100%}.filter-group{overflow-x:auto;max-width:100%}.facts{grid-template-columns:1fr;gap:14px}.device-details{padding:18px}.health-line{flex-direction:column-reverse;gap:10px}.field-row{align-items:stretch;flex-direction:column}.action-form>.field-row>.button{width:100%}.timeline-item{grid-template-columns:12px 1fr}.timeline-time{display:none}.timeline-item details{grid-column:2}.dialog-actions .button{width:auto}.copy-value button{opacity:1}.panel-header{align-items:flex-start;flex-direction:column}}
@media(max-width:900px){.dashboard-grid{grid-template-columns:minmax(0,1fr);grid-template-areas:"status" "fleet" "model" "firmware"}.facet-card{min-height:0}}
@media(max-width:640px){
  .topbar{gap:10px}.brand{font-size:14px}.brand>span:last-child{display:inline}.brand-mark{flex:0 0 auto}.main-nav{gap:10px}.main-nav a{font-size:13px}.icon-button{width:36px;height:36px;flex:0 0 auto}
  .dashboard-grid{gap:12px}.dashboard-fleet{grid-row:2}.dashboard-grid .panel-header{align-items:stretch}.dashboard-grid .toolbar{display:grid;grid-template-columns:1fr}.dashboard-grid .filter-group{width:max-content;max-width:100%}
  .device-table thead,.certificate-table thead{display:none}.device-table,.device-table tbody,.device-table tr,.certificate-table,.certificate-table tbody,.certificate-table tr{display:block;width:100%}
  .device-table tr,.certificate-table tr{padding:12px 14px;border-bottom:1px solid var(--border)}.device-table tr:last-child,.certificate-table tr:last-child{border-bottom:0}
  .device-table td,.certificate-table td{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:6px 0;border:0;text-align:right}.device-table td:first-child{padding-bottom:10px;text-align:left}.device-table td[data-label]:before,.certificate-table td[data-label]:before{content:attr(data-label);color:var(--muted);font-size:11px;font-weight:620;text-align:left}
  .device-table td:last-child{display:none}.certificate-table .certificate-actions{padding-top:10px}.certificate-table .certificate-actions .button{width:100%}
  .device-cell{width:100%}.device-tabs{margin-left:-12px;margin-right:-12px;padding:0 2px;gap:0;border-left:0;border-right:0;border-radius:0;scroll-snap-type:x proximity}.tab-btn{padding:11px 9px 9px;font-size:12px;scroll-snap-align:start}.tab-icon{width:17px;height:17px;margin-right:4px}.tab-count{margin-left:4px}
}
@media(max-width:360px){.brand>span:last-child{display:none}}
@media(max-width:640px){.history-record{grid-template-columns:1fr;gap:12px}.certificate-history{padding:0 14px}}
@media(max-height:360px){.modal-backdrop{padding:8px}.modal-card{max-height:calc(100vh - 16px)}.dialog-card{grid-template-columns:40px minmax(0,1fr);gap:10px;padding:14px 18px}.dialog-icon{width:36px;height:36px}.dialog-icon svg{width:20px;height:20px}.confirmation-identity{margin-top:8px;padding:7px 9px}.confirmation-warning{margin-top:7px}.dialog-actions{margin-top:0}}
.tag-list{display:inline-flex;flex-wrap:wrap;gap:6px}.tag-list.editable{display:flex;margin-bottom:14px;min-height:28px}
.tag{display:inline-flex;align-items:center;gap:4px;padding:2px 9px;border:1px solid var(--border);border-radius:999px;background:var(--surface-2,var(--bg));color:var(--text);font-size:12px;line-height:1.6}
button.tag.suggestion{cursor:pointer;font:inherit;font-size:12px}button.tag.suggestion:hover{border-color:var(--primary)}
.tag-remove{border:0;background:none;color:var(--muted);cursor:pointer;font-size:14px;line-height:1;padding:0 0 0 2px}.tag-remove:hover{color:var(--danger)}
.tag-suggestions{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:10px}
.device-buttons{display:flex;gap:9px;margin-top:16px}
.modal-body{padding:0 4px 4px}.modal-body .field{margin-top:12px}.form-error{color:var(--danger);margin:10px 0 0}
.task-group{margin-bottom:22px}.task-group-title{margin:0 0 10px;font-size:13px;color:var(--muted);font-weight:650;text-transform:uppercase;letter-spacing:.04em}
.task-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
.task-card h4{margin:0 0 4px;font-size:15px}.task-card p.secondary{margin:0 0 12px;line-height:1.5}.task-card .field{margin-bottom:12px}.task-card .result{margin:14px 0 0}
.task-steps{list-style:none;margin:10px 0 0;padding:0;font-size:13px}.task-steps li{margin:4px 0}.task-steps li.error{color:var(--danger)}.task-steps li.ok span:first-child{color:var(--success)}
details.advanced{margin-top:26px;padding-top:14px;border-top:1px solid var(--border)}details.advanced>p{margin:8px 0 14px}

/* Page transitions (see useRoute in spa.js). The root snapshot is always exactly the viewport, so there is no
   size or aspect-ratio change between old and new to stretch (a named content element differs in height per
   page, which squished it vertically). The header gets its own name so it is excluded from the slide. */
.topbar{view-transition-name:header}
@media(prefers-reduced-motion:no-preference){
::view-transition{background:var(--bg)}
::view-transition-group(root){animation:none}
::view-transition-old(root),::view-transition-new(root){animation-duration:.32s;animation-timing-function:cubic-bezier(.32,.72,0,1);animation-fill-mode:both;mix-blend-mode:normal}
html[data-nav=forward]::view-transition-old(root){animation-name:nav-out-left}
html[data-nav=forward]::view-transition-new(root){animation-name:nav-in-right}
html[data-nav=back]::view-transition-old(root){animation-name:nav-out-right}
html[data-nav=back]::view-transition-new(root){animation-name:nav-in-left}
html[data-nav=down]::view-transition-old(root){animation-name:nav-recede}
html[data-nav=down]::view-transition-new(root){animation-name:nav-in-below;z-index:2}
html[data-nav=up]::view-transition-old(root){animation-name:nav-out-below;z-index:2}
html[data-nav=up]::view-transition-new(root){animation-name:nav-restore}
}
@media(prefers-reduced-motion:reduce){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}
@keyframes nav-out-left{to{transform:translateX(-100%)}}
@keyframes nav-in-right{from{transform:translateX(100%)}}
@keyframes nav-out-right{to{transform:translateX(100%)}}
@keyframes nav-in-left{from{transform:translateX(-100%)}}
@keyframes nav-recede{to{transform:scale(.94);opacity:0}}
@keyframes nav-restore{from{transform:scale(.94);opacity:0}}
@keyframes nav-in-below{from{transform:translateY(100%)}}
@keyframes nav-out-below{to{transform:translateY(100%)}}

/* Device page tabs: the incoming panel slides in from the side of its tab. Only the new panel animates (no
   snapshot of a variable-height element, so nothing to stretch), and only when motion is welcome.
   will-change:transform is set unconditionally (not just while [data-direction] is present) so the browser
   keeps this on the same compositor layer before, during and after the animation -- without it, the layer is
   torn down the instant the animation ends, and the hand-off back to normal layout rounds sub-pixel position
   slightly differently, producing a visible 1-2px snap right as it "settles". */
.tab-view{will-change:transform}
@media(prefers-reduced-motion:no-preference){
.tab-view[data-direction=forward]{animation:tab-in-from-right .26s cubic-bezier(.32,.72,0,1)}
.tab-view[data-direction=back]{animation:tab-in-from-left .26s cubic-bezier(.32,.72,0,1)}
}
@keyframes tab-in-from-right{from{opacity:0;transform:translateX(32px)}}
@keyframes tab-in-from-left{from{opacity:0;transform:translateX(-32px)}}

/* Task cards: equal height across a row, buttons pinned to the bottom edge; results render under the group so
   a result never resizes one card out of line with its neighbours. */
.task-grid{align-items:stretch}
.task-card{display:flex;flex-direction:column;height:100%}
.task-card>.panel-body{display:flex;flex-direction:column;flex:1}
.task-card .task-action{margin-top:auto;padding-top:4px}
.task-result{margin-top:14px}.task-result-title{margin:0 0 6px;font-size:13px;color:var(--muted);font-weight:650}.task-result .result{margin:0}
.task-grid .panel+.panel{margin-top:0}
.heading-actions{display:flex;gap:9px;flex-wrap:wrap;align-items:center}

.onboarding h4{margin:18px 0 6px;font-size:14px}.onboarding h4:first-of-type{margin-top:14px}.onboarding p{line-height:1.55;margin:6px 0}
.onboarding code{padding:1px 6px;border-radius:5px;background:var(--surface-soft);border:1px solid var(--border);font-size:12.5px;word-break:break-all}
.steps{margin:8px 0 0;padding-left:22px}.steps li{margin:8px 0;line-height:1.55}
.command-block{position:relative;margin:8px 0}.command-block pre{margin:0;padding:12px 44px 12px 14px;border-radius:var(--radius);background:var(--surface-soft);border:1px solid var(--border);overflow-x:auto;font-size:12.5px;line-height:1.55;white-space:pre}
.command-block .copy-icon-btn{position:absolute;top:8px;right:8px;opacity:1}
details.onboarding-upgrade,details.setup-details{margin-top:14px}details.setup-details{margin:16px 0;border:1px solid var(--border);border-radius:10px}
details.setup-details>.panel-body{padding:14px 16px}
.interval-select{display:flex;align-items:center;gap:8px;margin-left:auto}.interval-select label{color:var(--muted);font-size:12px;font-weight:620}.interval-select select{max-width:260px}
.admin-field{max-width:320px;margin:14px 0}.admin-actions{display:flex;align-items:center;gap:12px;margin-top:6px}

/* accounts */
.auth-page{min-height:100vh;display:grid;place-items:center;padding:24px 16px}
.auth-card{width:100%;max-width:400px;padding:26px}.auth-card h1{margin:14px 0 16px;font-size:20px}.auth-card .field{margin-top:12px}
.auth-brand{display:flex;align-items:center;gap:9px;font-weight:650}.auth-submit{width:100%;margin-top:18px}
.user-menu{position:relative}.user-menu>summary{list-style:none;cursor:pointer}.user-menu>summary::-webkit-details-marker{display:none}
.remote-open-menu>summary[aria-disabled=true]{opacity:.48;cursor:not-allowed}
.user-chip{display:inline-flex;flex-direction:column;align-items:flex-start;padding:4px 10px;border:1px solid var(--border);border-radius:8px;font-size:13px;line-height:1.25;color:var(--text)}
.user-chip .user-role{color:var(--muted);font-size:11px}.user-chip.warn{color:#75500b;background:var(--warning-soft);border-color:#eedcae}
.user-menu-body{position:absolute;right:0;top:calc(100% + 6px);z-index:70;min-width:240px;padding:8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:0 8px 24px rgba(0,0,0,.14)}
.user-menu-id{display:flex;flex-direction:column;gap:2px;padding:6px 8px 10px;border-bottom:1px solid var(--border);margin-bottom:6px;font-size:13px}
.menu-item{display:block;width:100%;text-align:left;padding:8px;border:0;border-radius:6px;background:none;color:var(--text);font:inherit;cursor:pointer}.menu-item:hover{background:var(--surface-soft)}
.check-list{display:flex;flex-direction:column;gap:6px;margin-top:6px}.check{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--text)}.check input{width:auto}
.audit-detail{max-width:340px;word-break:break-word;font-size:12px}.audit-pager{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding:12px 16px}
.role-options{display:flex;flex-direction:column;gap:8px;margin-top:6px}
.role-option{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;color:var(--text)}
.role-option input{width:auto;margin-top:3px}.role-option span{display:flex;flex-direction:column;gap:2px;font-size:14px}.role-option.selected{border-color:var(--primary);background:var(--primary-soft)}
.page-actions{display:flex;gap:10px;margin-top:16px}.notice.ok{border-color:#b9e0c9;background:var(--success-soft);color:#1c6a44}
/* User menu: a light slide and fade as it opens. Only when motion is welcome. */
@media(prefers-reduced-motion:no-preference){
.user-menu[open]>.user-menu-body{animation:menu-in .16s cubic-bezier(.2,.8,.2,1);transform-origin:top right}
}
@keyframes menu-in{from{opacity:0;transform:translateY(-6px) scale(.98)}}
/* Form dialogs (Modal in spa.js) have no icon column: one column, title above the form. */
.form-modal{display:block}.form-modal>.dialog-copy h2{margin:0 0 12px;font-size:18px}.form-modal .dialog-actions{margin-top:20px}
.session-list{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:10px}.session-list li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid var(--border);border-radius:8px}
.badge{padding:2px 8px;border-radius:999px;background:var(--primary-soft);color:var(--primary);font-size:12px;font-weight:600}.session-list .badge,.device-table .badge{margin-left:8px}
/* Narrow screens: the navigation drops to its own scrollable row so the theme button and user menu stay reachable. */
@media(max-width:640px){.topbar{height:auto;flex-wrap:wrap;gap:8px 10px;padding:8px 12px 0}.brand>span:last-child{display:inline}.topbar-spacer{order:1}.icon-button{order:3}.user-menu{order:4}.brand{order:0}.main-nav{order:5;flex:0 0 100%;height:40px;gap:20px;overflow-x:auto;scrollbar-width:none;margin:0 -12px;padding:0 12px}.main-nav a{white-space:nowrap}.user-role{display:none}}
/* Dialogs fade in and rise a few pixels; reduced-motion users get the global near-zero duration. */
@keyframes backdrop-in{from{opacity:0}}
@keyframes modal-in{from{opacity:0;transform:translateY(8px) scale(.98)}}
.modal-backdrop{animation:backdrop-in .16s ease-out}.modal-card{animation:modal-in .18s cubic-bezier(.2,.8,.2,1)}
/* While a modal is open, the whole page behind it recedes as one piece: a quick scale-down + rounded corners
   that lets the backdrop's own dark tint show through as a thin border on every side, on top of the existing
   blur. .modal-backdrop always renders as a direct child of .route-view, a sibling of that page's own content
   (never nested inside it) -- :has() on #app catches it regardless of which page/modal, and the transform only
   ever targets its siblings, never the fixed-position backdrop itself (a transform on an ancestor of
   .modal-backdrop would otherwise hijack its fixed positioning, and #app can be taller than one screenful --
   its own scroll height, not the viewport -- so scaling #app itself would also make the backdrop cover the
   wrong area and mis-center the dialog; scaling .topbar and the page content as separate siblings avoids both).
   The two pieces are scaled independently (.topbar is a tiny 58px box; the page content beneath it can be
   hundreds of px tall), so a plain `transform:scale()` on each -- which shrinks toward EACH ELEMENT'S OWN
   center -- pulls them toward two different points and visibly tears them apart at the seam. Both instead
   share one transform-origin: the viewport's true vertical center (50vh down from y=0, which is exactly where
   .topbar starts; the page content starts --topbar-h below that, so its origin subtracts that back out) --
   scaling everything toward the same point keeps the header and content moving as a single rigid unit, with
   no gap ever opening between them. */
:root{--topbar-h:58px}
/* transform-origin is set here, unconditionally, rather than inside the :has() rules below: it isn't in the
   transition list (only transform/border-radius are), so if it were only ever set while a modal is open, it
   would snap straight to its default (the element's own center) the instant the modal closes -- shifting the
   scale's pivot point discontinuously right as the reverse transition starts, which reads as the header
   "snapping" before the rest of the (still-smooth) shrink-back plays out. Keeping it constant at all times, on
   both states, means only the scale factor itself is ever animated. */
#app>.topbar{transition:transform .22s cubic-bezier(.2,.8,.2,1),border-radius .22s ease;transform-origin:50% 50vh}
#app>.route-view>*{transition:transform .22s cubic-bezier(.2,.8,.2,1),border-radius .22s ease;transform-origin:50% calc(50vh - var(--topbar-h))}
#app:has(.modal-backdrop)>.topbar{transform:scale(.98);border-radius:14px 14px 0 0}
/* .offline-banner is excluded here (not just .modal-backdrop): it can sit as an extra sibling ahead of the
   actual page content, and this rule assumes whatever it selects is the single, last piece that should get
   bottom rounding -- rounding the banner's bottom too would leave a seam between it and the page beneath it,
   the same "torn apart" problem the shared transform-origin above exists to prevent between the header and
   the page. Simplest fix: the banner just doesn't participate in the recede effect at all, the same as the
   header/topbar already sitting outside this rule's scope for its own, unrelated reason. */
#app:has(.modal-backdrop)>.route-view>*:not(.modal-backdrop):not(.offline-banner){transform:scale(.98);border-radius:0 0 14px 14px;overflow:hidden}
@media(max-width:640px){:root{--topbar-h:auto}}
/* Organization switcher: sits beside the user menu and reuses its dropdown; tinted while a filter is active. */
.org-switch{list-style:none;display:flex;align-items:center;gap:7px;height:36px;padding:0 11px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);color:var(--muted);font-size:13px;font-weight:560;cursor:pointer;user-select:none}
.org-switch::-webkit-details-marker{display:none}.org-switch:hover{color:var(--text)}.org-switch .ti{width:18px;height:18px;flex:0 0 auto}
.org-switch.filtered{border-color:var(--primary);background:var(--primary-soft);color:var(--primary)}
.org-switch-name{max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu-heading{padding:4px 8px 6px;font-size:11px;font-weight:650;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.menu-item.current{color:var(--primary);font-weight:620}.menu-item.current:before{content:"\2713";display:inline-block;width:18px}.menu-item[role=menuitemradio]:not(.current){padding-left:26px}
@media(max-width:640px){.org-switch-name{display:none}.org-switch{padding:0 9px}.org-menu{order:3}.icon-button{order:2}}
.fact-note{margin-top:4px;font-size:12px;max-width:34ch}
/* Add-device type chooser and the one-time enrollment command. */
.segmented{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:2px 0 14px}
.segmented button{display:flex;flex-direction:column;align-items:flex-start;gap:2px;padding:9px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);color:var(--text);font:inherit;font-weight:600;text-align:left;cursor:pointer}
.segmented button span{font-size:12px;font-weight:400;color:var(--muted)}
.segmented button.active{border-color:var(--primary);background:var(--primary-soft);color:var(--primary)}
.segmented button.active span{color:inherit;opacity:.85}
.code-block{position:relative;margin:10px 0 14px}
.code-block pre{margin:0;padding:12px 84px 12px 12px;overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface-soft);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;white-space:pre-wrap;word-break:break-all}
.copy-button{position:absolute;top:8px;right:8px;padding:4px 10px;border:1px solid var(--border);border-radius:6px;background:var(--surface);color:var(--text);font:inherit;font-size:12px;cursor:pointer}
.token-created{margin:12px 0;padding:12px;border:1px solid var(--primary);border-radius:var(--radius);background:var(--primary-soft)}
.token-created .code-block{margin:8px 0}.token-heading{margin:18px 0 8px;font-size:14px}.token-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
