/* =============================================================================
   AEROSOPHIA DRONE DETECT · console.css
   Console layout + domain components. Loads LAST (after aerosophia-ds.css,
   aerosophia-components.css and airspace-ops.css). Token-only: every colour is a
   var(--*) from the platform DS or the Airspace Ops layer (navy chrome, MAP:grey,
   severity ALWAYS with its shape ● ◆ ▲ ⬣, lime only for live signals).
   ============================================================================= */

/* ------------------------------------------------------------------ 0 fonts */
/* every weight the console sets is a real face (static WOFF2 instances of the upstream variable fonts, licence files beside
   them: OFL-OpenSans.txt, OFL-JetBrainsMono.txt) [REMOVAL-257] the TTF @font-face rules replaced: 500 and 800 drew the
   600 and 700 files and Mono 700 the 600 file, faux weights (G21); the TTFs stay for the user-guide build tools */
@font-face{font-family:"Open Sans";font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/OpenSans-400.woff2) format("woff2");}
@font-face{font-family:"Open Sans";font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/OpenSans-500.woff2) format("woff2");}
@font-face{font-family:"Open Sans";font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/OpenSans-600.woff2) format("woff2");}
@font-face{font-family:"Open Sans";font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/OpenSans-700.woff2) format("woff2");}
@font-face{font-family:"Open Sans";font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/OpenSans-800.woff2) format("woff2");}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/JetBrainsMono-400.woff2) format("woff2");}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/JetBrainsMono-600.woff2) format("woff2");}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/JetBrainsMono-700.woff2) format("woff2");}

/* ------------------------------------------------------------------- 1 base */
:root[data-palette="airspace"]{--dd-rail-w:64px; --dd-top-h:52px; --dd-lp-w:328px; --dd-detail-w:388px; --dd-gap:12px;
  --dd-chrome-fg:#E7EEF6; --dd-chrome-muted:#8BA2BB; --dd-chrome-line:rgba(255,255,255,.12);}
/* navy chrome (rail, topbar, mobile header, login glow), the same in both themes. Its gradient reuses the platform's
   --topbar-bg / --sidebar-bg-top (#0D2235) and --sidebar-bg-mid (#091828). Text steps from the strongest to the faintest:
   --dd-chrome-subtle is the lightest step of the platform's --sidebar-fg-muted hue that holds 4.5:1 on the whole rail
   (#091828 and #050B13). Hairlines and hover washes are white at the alpha their rule sets; state hues on chrome have a
   text tone and a mark tone (icons, borders). */
:root[data-palette="airspace"]{--dd-chrome-mid:#0B1D2E; --dd-chrome-edge:#02060C;
  --dd-chrome-fg-strong:var(--neutral-0); --dd-chrome-fg-2:#C9D7E4; --dd-chrome-fg-3:#B8C6D6; --dd-chrome-fg-4:#9FB2C6;
  --dd-chrome-subtle:#6E8298; --dd-chrome-tint-rgb:255,255,255;
  --dd-chrome-accent:#38BDF8; --dd-chrome-accent-rgb:56,189,248; --dd-chrome-on-accent:#04121F; --dd-chrome-live-rgb:168,230,58;
  --dd-chrome-ok:#7BD7A2; --dd-chrome-warn:#EFCE6F; --dd-chrome-error:#F48C9A;
  --dd-chrome-warn-mark:#F5B301; --dd-chrome-warn-rgb:245,179,1; --dd-chrome-error-mark:#FF3B4E; --dd-chrome-error-rgb:255,59,78;
  --dd-hdg-shadow:rgba(0,0,0,.7);}
:root[data-palette="airspace"][data-theme="light"]{--dd-login-glow:#E0F2FE;}
/* stacking (DESIGN-SYSTEM.md §2.16): the live map's floating panels sit on --z-dd-panel inside the stage, which is
   its own stacking context; the layers on body keep this order: guide (--z-modal) < modal scrim < context menu < toasts
   < busy notice < skip link. Leaflet panes of the console's own layers, between the library's overlay (400) and
   marker (600) panes; the scripts read them (DD.map.pane). */
:root[data-palette="airspace"]{--z-dd-panel:20; --z-dd-scrim:calc(var(--z-modal) + 1); --z-dd-cm:calc(var(--z-modal) + 2);
  --z-dd-busy:calc(var(--z-toast) + 1);
  --dd-pane-coverage:340; --dd-pane-areas:345; --dd-pane-zones:350; --dd-pane-controls:355; --dd-pane-objects:360;
  --dd-pane-trails:410; --dd-pane-links:420; --dd-pane-labels:430; --dd-pane-cov-marks:435; --dd-pane-pilots:590;}
/* map focus (R1-31): opacity of a faded drone marker (its fill or ink keeps 3:1 on the grey basemap; light needs
   more for the dashed ink of non-cooperative drones), of the other drones while one is selected (owner decision
   4 Oct 2026: clearly dimmed, below 3:1, so the selected drone stands out), of faded lines and of faded objects,
   rings and zones */
:root[data-palette="airspace"]{--dd-focus-fade:.74; --dd-focus-fade-select:.4; --dd-focus-fade-line:.3; --dd-focus-fade-area:.4;}
:root[data-palette="airspace"][data-theme="light"]{--dd-focus-fade:.81;}
/* QR code of a dispatch link: dark modules on white in both themes, which scanners read best (a light-on-dark code often fails) */
:root[data-palette="airspace"]{--dd-qr-fg:var(--neutral-900); --dd-qr-bg:var(--neutral-0); --dd-qr-size:200px;}
html,body{height:100%;}
body.dd{background:var(--canvas); color:var(--text-primary); overflow:hidden;}
body.dd-scroll{overflow:auto;}
.dd-sprite{position:absolute; width:0; height:0; overflow:hidden;}
.dd-hatch-nfz__fill{fill:var(--zone-nfz-fill);} .dd-hatch-nfz__line{fill:var(--zone-nfz-hatch);}
.dd-hatch-cov__fill{fill:var(--cov-mask);} .dd-hatch-cov__line{fill:var(--cov-hatch);} .dd-hatch-cov-lost__line{fill:var(--cov-lost-hatch);}
.ic{width:16px; height:16px; flex:0 0 auto; display:inline-block; vertical-align:-3px;}
/* severity shapes: 12 px at least wherever no severity word sits beside them (DS-T06); the triangle and the octagon
   take a pixel more, as they fill less of their box */
.shp{width:12px; height:12px; flex:0 0 auto; display:inline-block; vertical-align:-2px;}
.shp--low{fill:var(--sev-low-ink);} .shp--medium{fill:var(--sev-medium-ink);}
.shp--high{fill:var(--sev-high-ink); width:13px; height:13px;} .shp--critical{fill:var(--sev-critical-ink); width:13px; height:13px;}
.dd-mono,.dd-mono *{font-family:var(--font-mono); font-variant-numeric:tabular-nums;}
.dd-muted-sm{color:var(--text-muted); font-size:11.5px;}
:root[data-theme="light"] .dd-only-dark{display:none !important;}
:root[data-palette="airspace"]:not([data-theme="light"]) .dd-only-light{display:none !important;}
.dd-skip{position:absolute; left:-9999px; top:8px; z-index:var(--z-swal-top); background:var(--accent); color:var(--on-accent); padding:var(--space-2) 14px; border-radius:var(--radius-md); font-weight:700;}
.dd-skip:focus{left:8px;}
[hidden]{display:none !important;}
.dd-kbd{font-family:var(--font-mono); font-size:10px; color:var(--text-muted); border:1px solid var(--border-default); border-radius:4px; padding:0 5px; line-height:16px;}
/* Chrome keeps room for a search field's clear button while the field is empty and the button unseen: an empty field
   gives that room to its placeholder, and the button comes back with the first character */
input[type=search]:placeholder-shown::-webkit-search-cancel-button{display:none;}
.btn .ic{width:15px; height:15px;}
.btn-icon .ic{width:17px; height:17px;}
.dd-livetag{display:inline-flex; align-items:center; gap:5px; font:700 10px var(--font-mono); letter-spacing:.06em; color:var(--live-ink);}

/* --------------------------------------------------------------- 2 shell */
.dd-app{height:100vh;}
.dd-rail{padding-top:10px;}
.dd-rail-brand{height:52px; align-items:center; margin-bottom:var(--space-1);}
/* the rail heads the page with the logo (owner decision 8 Oct 2026): expanded, the logo guide's dark horizontal lockup,
   156 px wide, the most that leaves 1 X of clear space (10 px) before the collapse chevron; collapsed, the full mark at
   44 px, centred in the 64 px rail under its 46 px expand toggle. The lockup's mark is centred where the collapsed mark
   is, so the logo does not jump when the rail toggles; while the rail opens, its row clips the lockup. Only the logo
   shown is in the accessibility tree, and it names the product: the topbar carries no logo */
.dd-rail-mark{display:block; flex:0 0 auto; width:44px; height:44px;}
.dd-rail-mark img{display:block; width:44px; height:44px;}
.dd-rail-lockup{display:none; flex:0 1 auto; min-width:0; margin-left:var(--space-1); overflow:hidden;}
.dd-rail-lockup img{display:block; width:156px; max-width:none; height:auto;}
.dd-rail.rail--x .dd-rail-mark{display:none;}
.dd-rail.rail--x .dd-rail-lockup{display:block;}
/* [REMOVAL-269] .dd-rail-logo box (the lockup clipped to its mark, with REMOVAL-029's note), its hover tint, its img
   rule, the --dd-logo-h height and the flyout lockups' width (REMOVAL-234's rule) dropped: the rail shows mark-small
   only and the brand flyout carries no lockup (owner decision 2 Oct 2026) */
.dd-rail .rail__item{color:var(--dd-chrome-fg-4);}
.dd-rail .rail__item:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* inset: the rail sits on the window's left edge [REMOVAL-184] outline-offset:1px replaced: the window cut off the ring's left side */
.dd-rail .rail__flyout--tip{left:calc(100% + 2px);}
.dd-rail-badge{position:absolute; top:3px; right:2px; min-width:16px; height:16px; padding:0 var(--space-1); border-radius:var(--radius-md); background:var(--danger-500); color:var(--dd-chrome-fg-strong);
  font:700 9.5px/16px var(--font-mono); text-align:center; box-shadow:0 0 0 2px var(--dd-chrome-mid);}
.dd-rail-ver{font-family:var(--font-mono); font-size:9.5px; color:var(--dd-chrome-subtle);}
.dd-shell{flex:1; min-width:0; display:flex; flex-direction:column; height:100vh;}
.dd-topbar{height:var(--dd-top-h); flex:0 0 var(--dd-top-h); gap:var(--space-4); padding:0 var(--space-4) 0 18px;
  background:linear-gradient(90deg,var(--topbar-bg) 0%,var(--dd-chrome-mid) 60%,var(--sidebar-bg-mid) 100%); border-bottom:1px solid var(--dd-chrome-edge);}
/* [REMOVAL-384] .dd-product and .dd-product__lockup (the topbar lockup, 180 px, and its note on the guide's section 5
   exception, G15) dropped: the logo heads the side menu instead (owner decision 8 Oct 2026) */
/* [REMOVAL-233] .dd-product{font-size…}, .dd-product__a and .dd-product__b dropped: the topbar shows the logo lockup instead of the name set in live type (owner decision 2 Oct 2026, G15) */
.dd-ctx .seg{cursor:default;}
.dd-ctx .seg .ic{width:13px; height:13px; color:var(--sky);}
.dd-util{gap:var(--space-3);}
.dd-topdiv{width:1px; height:22px; background:var(--dd-chrome-line);}
/* live indicator — lime ONLY while the socket is connected */
.dd-live{display:inline-flex; align-items:center; gap:7px; height:28px; padding:0 11px; border-radius:var(--radius-pill);
  border:1px solid rgba(var(--dd-chrome-tint-rgb),.14); background:rgba(var(--dd-chrome-tint-rgb),.05); color:var(--dd-chrome-muted);
  font:700 11px var(--font-mono); letter-spacing:.06em; white-space:nowrap;}
.dd-live__dot{width:8px; height:8px; border-radius:var(--radius-round); border:1.5px solid currentColor; flex:0 0 8px;}
.dd-live__n{color:var(--dd-chrome-fg-strong); font-weight:700;}
.dd-live[data-state="live"]{border-color:rgba(var(--dd-chrome-live-rgb),.38); color:var(--live-400); background:rgba(var(--dd-chrome-live-rgb),.07);}
.dd-live[data-state="live"] .dd-live__dot{background:var(--live-400); border-color:var(--live-400); animation:ds-live-pulse var(--live-dur-pulse) ease-out infinite; box-shadow:0 0 0 0 rgba(var(--dd-chrome-live-rgb),.5);}
.dd-live[data-state="polling"]{color:var(--dd-chrome-warn); border-color:rgba(var(--dd-chrome-warn-rgb),.35);}
.dd-live[data-state="polling"] .dd-live__dot{border-style:dashed;}
.dd-live[data-state="offline"],.dd-live[data-state="stale"]{color:var(--dd-chrome-error); border-color:rgba(var(--dd-chrome-error-rgb),.4);}
.dd-live[data-state="stale"] .dd-live__dot{border-style:dotted;}
@media (prefers-reduced-motion: reduce){ .dd-live[data-state="live"] .dd-live__dot{animation:none;} }
.dd-chip-sensors{display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 10px; border-radius:var(--radius-pill);
  border:1px solid rgba(var(--dd-chrome-tint-rgb),.14); color:var(--dd-chrome-fg-2); font-size:12px; font-weight:600; white-space:nowrap;}
.dd-chip-sensors:hover{color:var(--dd-chrome-fg-strong); background:rgba(var(--dd-chrome-tint-rgb),.06);}
.dd-chip-sensors b{font-family:var(--font-mono); font-weight:700; color:var(--dd-chrome-fg-strong);}
.dd-chip-sensors .ic{width:15px; height:15px;}
.dd-chip-sensors[data-state="ok"] .ic{color:var(--dd-chrome-ok);}
.dd-chip-sensors[data-state="warn"]{border-color:rgba(var(--dd-chrome-warn-rgb),.45);} .dd-chip-sensors[data-state="warn"] .ic{color:var(--dd-chrome-warn-mark);}
.dd-chip-sensors[data-state="error"]{border-color:rgba(var(--dd-chrome-error-rgb),.5);} .dd-chip-sensors[data-state="error"] .ic{color:var(--dd-chrome-error-mark);}
/* area-of-responsibility pill: what this user may see (never lime, never a severity hue); dashed = limited */
.dd-area-pill{display:inline-flex; align-items:center; gap:6px; height:28px; min-width:0; max-width:320px; padding:0 11px; border-radius:var(--radius-pill);
  border:1px solid var(--dd-chrome-line); color:var(--dd-chrome-fg); font-size:12px; font-weight:600; white-space:nowrap;}
.dd-area-pill .ic{width:15px; height:15px; flex:0 0 15px; color:var(--aor-chrome);}
.dd-area-pill__lbl{min-width:0; overflow:hidden; text-overflow:ellipsis;}
.dd-area-pill[data-scope="areas"]{border-style:dashed; border-color:var(--aor-chrome);}
.dd-area-pill[data-scope="none"]{border-style:dotted; border-color:var(--aor-chrome);}
.dd-evcount{color:var(--dd-chrome-fg-3);}
.dd-evcount .ic{width:19px; height:19px;}
.dd-evcount .topbar__badge{font-family:var(--font-mono); top:-4px; right:-8px; padding:1px 5px; font-size:9.5px; box-shadow:0 0 0 2px var(--topbar-bg);}
.dd-theme-toggle,.dd-helpbtn{color:var(--dd-chrome-fg-3); border-radius:var(--radius-md); padding:6px;}
.dd-theme-toggle:hover,.dd-helpbtn:hover{background:rgba(var(--dd-chrome-tint-rgb),.08);}
.dd-lang{position:relative; display:inline-flex; border:1px solid rgba(var(--dd-chrome-tint-rgb),.16); border-radius:var(--radius-pill); padding:2px;}
.dd-lang__btn{display:inline-flex; align-items:center; gap:5px; font:700 11px var(--font-mono); color:var(--dd-chrome-fg-3); padding:3px var(--space-2); border:none; background:none; border-radius:var(--radius-pill); letter-spacing:.04em; cursor:pointer;}
.dd-lang__btn:hover,.dd-lang__btn[aria-expanded="true"]{color:var(--dd-chrome-fg-strong); background:rgba(var(--dd-chrome-tint-rgb),.08);}
.dd-lang__btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.dd-lang__btn .ic{width:14px; height:14px;}
.dd-lang__btn .dd-lang__chev{width:12px; height:12px; opacity:.7;}
/* [REMOVAL-027] .dd-lang__btn.is-on (segmented NL/EN state) dropped: the current language is the menu item with aria-checked="true" */
.dd-lang__menu{min-width:190px;}
.dd-menu.dd-menu--up{top:auto; bottom:calc(100% + 8px);}
.dd-lang__item{text-decoration:none;}
.dd-lang__name{flex:1; min-width:0;}
.dd-lang__code{font:600 11px var(--font-mono); color:var(--text-muted); letter-spacing:.04em;}
.dd-lang__item .dd-lang__check{width:14px; height:14px; color:var(--accent);}
.dd-lang__item[aria-checked="false"] .dd-lang__check{visibility:hidden;}
.dd-lang__item[aria-checked="true"]{color:var(--text-primary); font-weight:600;}
.dd-user{position:relative;}
.dd-user__btn{display:flex; align-items:center; gap:var(--space-2); background:none; border:1px solid transparent; border-radius:var(--radius-pill); padding:2px var(--space-2) 2px 2px; color:var(--dd-chrome-fg);}
.dd-user__btn:hover{background:rgba(var(--dd-chrome-tint-rgb),.07); border-color:var(--dd-chrome-line);}
.dd-user__btn .topbar__avatar{width:28px; height:28px; background:var(--dd-chrome-accent); color:var(--dd-chrome-on-accent);}
.dd-user__nm{font-size:12.5px; font-weight:600; max-width:140px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.dd-user__chev{width:13px; height:13px; color:var(--dd-chrome-muted);}
.dd-menu{position:absolute; right:0; top:calc(100% + 8px); min-width:230px; background:var(--surface-0); border:1px solid var(--border-default);
  border-radius:var(--radius-md); box-shadow:var(--elev-4); padding:6px; z-index:var(--z-map-popover);}
.dd-menu__hd{display:flex; flex-direction:column; gap:2px; padding:var(--space-2) 10px 10px; border-bottom:1px solid var(--border-subtle); margin-bottom:var(--space-1);}
.dd-menu__hd b{color:var(--text-primary);} .dd-menu__hd .dd-mono{font-size:11px; color:var(--text-muted);}
.dd-roles{display:flex; gap:var(--space-1); flex-wrap:wrap; margin-top:6px;}
.dd-menu__item{display:flex; align-items:center; gap:9px; width:100%; padding:var(--space-2) 10px; border:none; background:none; border-radius:7px; color:var(--text-secondary); font-size:13px; text-align:left;}
.dd-menu__item:hover,.dd-menu__item:focus-visible{background:var(--surface-1); color:var(--text-primary);}
.dd-menu__form{margin:0;}
/* the organisation switcher (user menu) and the organisation in the context pill: users who work for several (R1-91b) */
.dd-menu__group{display:flex; flex-direction:column; padding-bottom:var(--space-1); margin-bottom:var(--space-1); border-bottom:1px solid var(--border-subtle);}
.dd-menu__lbl{padding:var(--space-1) var(--space-3); font:600 10.5px var(--font-mono); letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted);}
.dd-tenant{max-width:320px;}
.dd-tenant__nm{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.dd-tenant__role{font-size:11px; color:var(--text-muted); white-space:nowrap;}
.dd-tenant .dd-tenant__check{width:14px; height:14px; flex:0 0 14px; color:var(--accent);}
.dd-tenant[aria-checked="false"] .dd-tenant__check{visibility:hidden;}
.dd-tenant[aria-checked="true"]{color:var(--text-primary); font-weight:600;}
.dd-tenant[aria-busy="true"]{cursor:progress; opacity:.7;}
.dd-ctx__org b{display:inline-block; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom;}
.dd-stage{flex:1; min-height:0; position:relative; outline:none; isolation:isolate;} /* page panels stack inside the stage, under the topbar and its menus, whatever their z-index; layers that must cover the topbar (modals, context menu, toasts) live outside it, on body */
.dd-stage--map{overflow:hidden;}
.dd-stage--page{overflow:auto; background:var(--canvas);}

/* ------------------------------------------------------------ 3 map base */
.dd-map,.leaflet-container.dd-map{background:var(--map-bg); font-family:var(--font); color:var(--text-primary);}
.dd-mapwrap{position:absolute; inset:0; z-index:0;} .dd-mapwrap:focus-visible{outline-offset:-2px;} /* inset: the map fills its panel, which clips an outer ring */
.dd-map .leaflet-tile-pane{opacity:.96;}
/* [REMOVAL-198] Moved to airspace-ops.css --map-tiles-grey, --map-tiles-grey-invert, --map-tiles-osm and --map-tiles-sat:
   the literal filter lists of the basemap treatments, which the 3D view now reads from the same tokens */
/* basemaps (filter lists: airspace-ops.css --map-tiles-*, which the 3D view turns into its raster paint): grey without
   dark tiles (PDOK grijs) is inverted towards --map-bg; OSM and satellite are dimmed a little in the dark theme (owner
   decision 2 Oct 2026, G31), and overlays get a --map-bg casing to stay legible. The vector grey (dd-tiles--vector,
   G03, without the dd-tiles--grey class) is drawn in the --map-* tokens themselves and takes no filter */
:root[data-palette="airspace"] .dd-tiles--grey{filter:var(--map-tiles-grey);}
/* each repaint of a vector tile resets its canvas size; contained, it no longer leaves the page's layout to redo
   (the label decluttering's first read pays that layout) */
.dd-tiles--vector canvas.leaflet-tile{contain:strict;}
:root[data-palette="airspace"] .dd-tiles--grey.dd-tiles--invert{filter:var(--map-tiles-grey-invert);}
:root[data-palette="airspace"] .dd-tiles--osm{filter:var(--map-tiles-osm);}
:root[data-palette="airspace"] .dd-tiles--sat{filter:var(--map-tiles-sat);}
.dd-map[data-basemap]:not([data-basemap="grey"]):not([data-basemap=""]) .leaflet-map-pane > .leaflet-pane:not(.leaflet-tile-pane){filter:drop-shadow(0 0 1px var(--map-bg)) drop-shadow(0 0 1px var(--map-bg));}
/* Leaflet zoom buttons in the tool-rail look */
.dd-map .leaflet-bar{border:1px solid var(--border-subtle); border-radius:9px; overflow:hidden; box-shadow:var(--elev-2);}
.dd-map .leaflet-bar a,.dd-map .leaflet-bar a:hover{width:34px; height:34px; line-height:34px; background:var(--surface-0); color:var(--text-secondary); border-bottom:1px solid var(--surface-2);}
.dd-map .leaflet-bar a:last-child{border-bottom:none;}
.dd-map .leaflet-bar a:hover{background:var(--surface-1); color:var(--accent);}
.dd-map .leaflet-bar a.leaflet-disabled{background:var(--surface-0); color:var(--text-muted);}
.dd-map .leaflet-bar a:focus-visible,.dd-bm-ctl button:focus-visible,.tool-rail .grp button:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* inset: a tool group clips an outer ring */
/* basemap switcher (live legend panel + compact map control on the other maps) */
.dd-basemaps{border:0; margin:0 0 var(--space-1); padding:0; min-width:0;}
.dd-basemaps legend{padding:0;}
.dd-basemaps__opt{display:flex; align-items:center; gap:var(--space-2); padding:3px 0; font-size:12px; color:var(--text-secondary); cursor:pointer;}
.dd-basemaps__opt input{accent-color:var(--accent); margin:0;}
.dd-basemaps__opt:has(input:checked){color:var(--text-primary); font-weight:600;}
.dd-bm-ctl.leaflet-control{z-index:801;}
.dd-bm-ctl .tool-rail button{width:34px; height:34px;}
.dd-bm-panel{position:absolute; top:calc(100% + 6px); right:0; width:180px; padding:10px var(--space-3); color:var(--text-secondary);}
.leaflet-left .dd-bm-panel{right:auto; left:0;}
.leaflet-bottom .dd-bm-panel{top:auto; bottom:calc(100% + 6px);}
.dd-map .leaflet-control-attribution{background:color-mix(in srgb,var(--surface-0) 80%,transparent); color:var(--text-muted); font-size:10px; border-radius:var(--radius-sm) 0 0 0; padding:1px 6px;}
.dd-map .leaflet-control-attribution a{color:var(--text-secondary);} .dd-map .leaflet-control-attribution a:focus-visible{outline-offset:-2px;} /* inset: the attribution sits on the map's bottom edge */
.dd-map .leaflet-interactive:focus{outline:none;}
.dd-map path.leaflet-interactive:focus-visible{outline:2px solid var(--accent); outline-offset:2px;} /* the ring around the focused shape's bounding box [REMOVAL-187] outline:none; stroke-width:3 replaced: no visible change on a shape already drawn at 3 px, such as the dispatch page's start point */
.dd-statusbar{right:var(--dd-gap); bottom:24px; z-index:var(--z-map-overlay); padding:5px 10px; transition:right var(--dur-base) var(--ease), bottom var(--dur-base) var(--ease);}

/* zones (styles from airspace-ops .zone--*) + labels */
.dd-map .zone{stroke-linejoin:round;}
.dd-map .zone--nfz{fill-opacity:1;}
.dd-zlabel span,.dd-olabel,.dd-ring-lbl span,.dd-maplabel span{font-family:var(--font-mono); font-size:10px; font-weight:600; letter-spacing:.04em; white-space:nowrap;}
.dd-zlabel span{position:absolute; left:0; top:6px; transform:translateX(-50%); padding:2px 7px; border-radius:4px; background:var(--map-label-bg);}
.dd-zlabel--nfz span{color:var(--zone-nfz-stroke); border:1px dashed color-mix(in srgb,var(--zone-nfz-stroke) 60%,transparent);}
.dd-zlabel--protected span{color:var(--zone-protected-stroke);} .dd-zlabel--allow span{color:var(--zone-allow-stroke);} .dd-zlabel--monitor span{color:var(--zone-monitor-stroke);}
.dd-zlabel--control span{color:var(--zone-control-stroke); border:1px solid color-mix(in srgb,var(--zone-control-stroke) 45%,transparent);}
.leaflet-tooltip.dd-olabel{background:var(--map-label-bg); border:0; box-shadow:none; color:var(--zone-protected-stroke); padding:2px 7px; border-radius:4px; display:flex; flex-direction:column; align-items:center; line-height:1.25;}
.leaflet-tooltip.dd-olabel::before{display:none;}
.dd-olabel__n{font-weight:700;}
.dd-olabel__p{font-size:8.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted);}
.dd-z-far .leaflet-tooltip.dd-olabel .dd-olabel__p{display:none;}
.dd-z-far .dd-zlabel span{font-size:9px;}
.dd-obj{cursor:pointer;}
.dd-obj--high{stroke-width:2.2;}
.dd-map path.dd-obj:hover{fill:color-mix(in srgb,var(--zone-protected-stroke) 16%,transparent);}
/* [REMOVAL-199] Moved to airspace-ops.css --zone-ring-dash, --map3d-drop-dash and --map3d-open-top-dash: the dash literals
   3 5 (protection rings), 2 3 (3D drop line) and 6 5 (3D open band top), so both maps take one value */
.dd-ring{fill:none; stroke:var(--zone-protected-stroke); stroke-width:1.1; stroke-dasharray:var(--zone-ring-dash); vector-effect:non-scaling-stroke;}
.dd-ring--100{stroke-opacity:.8;} .dd-ring--200{stroke-opacity:.58;} .dd-ring--500{stroke-opacity:.38;}
.dd-ring-lbl span{display:inline-block; color:var(--zone-protected-stroke); opacity:.85; font-size:9px; padding:0 var(--space-1); border-radius:3px; background:var(--map-label-bg);}
.dd-map:not(.dd-z-near) .dd-ring-lbl{display:none;}

/* sensor coverage (shapes: airspace-ops §5.9): stations and lost-coverage labels stay neutral, the state is the icon */
.dd-station-icon,.dd-covlbl{width:0; height:0; background:none; border:0;} /* [REMOVAL-235] !important dropped from width and height: Leaflet writes the icon's iconSize [0, 0] on the element itself (G22) */
.dd-station{position:absolute; transform:translate(-50%,-50%); display:inline-flex; align-items:center; gap:2px; padding:2px var(--space-1) 2px 2px; border-radius:var(--radius-md);
  background:var(--map-label-bg); box-shadow:var(--elev-1); color:var(--text-primary); pointer-events:auto; cursor:default;}
.dd-station .src-chip--icon{width:20px; height:20px; border-radius:var(--radius-sm);}
.dd-station .src-chip svg{width:12px; height:12px; flex:0 0 12px;}
.dd-station__st{width:12px; height:12px; flex:0 0 12px;}
.dd-station[data-class="unavailable"]{box-shadow:none; outline:1.5px solid var(--cov-lost-edge);}
.dd-covlbl span{position:absolute; left:0; top:16px; transform:translateX(-50%); display:inline-flex; align-items:center; gap:var(--space-1); padding:2px 7px; border-radius:4px;
  background:var(--map-label-bg); color:var(--text-primary); border:1px solid var(--cov-lost-edge); font-family:var(--font-mono); font-size:10px; font-weight:600; white-space:nowrap;}
.dd-covlbl .ic{width:11px; height:11px; flex:0 0 11px; color:var(--cov-lost-edge);}
.dd-z-far .dd-station__st{display:none;}
.dd-cov-stale .leaflet-ddCoverage-pane,.dd-cov-stale .leaflet-ddCovMarks-pane{opacity:.45; filter:grayscale(.6);}

/* trails (severity ink; solid = cooperative, dashed = non-cooperative) */
.trail.sev-low{--c:var(--sev-low-ink);} .trail.sev-medium{--c:var(--sev-medium-ink);}
.trail.sev-high{--c:var(--sev-high-ink);} .trail.sev-critical{--c:var(--sev-critical-ink);}
.dd-map .trail{stroke-width:2.2;}
.dd-pilot-link{fill:none; stroke:var(--text-secondary); stroke-width:1.4; stroke-dasharray:4 5; stroke-linecap:round; opacity:.85;}
/* [REMOVAL-243] .dd-pilot-link.is-viol (always --sev-high-ink) replaced: the line takes the pilot-distance violation's own severity ink through data-sev, and its label that ink and shape (G04, G13) */
.dd-pilot-link[data-sev]{opacity:1;}
.dd-pilot-link[data-sev="low"]{stroke:var(--sev-low-ink);} .dd-pilot-link[data-sev="medium"]{stroke:var(--sev-medium-ink);}
.dd-pilot-link[data-sev="high"]{stroke:var(--sev-high-ink);} .dd-pilot-link[data-sev="critical"]{stroke:var(--sev-critical-ink);}
.dd-eta-line{fill:none; stroke:var(--text-secondary); stroke-width:1.5; stroke-dasharray:1 6; stroke-linecap:round; opacity:.9;}
/* an ETA of two minutes or less is urgent: brighter, heavier and denser, never a severity hue (G12) */
.dd-eta-line[data-urgent]{stroke:var(--text-primary); stroke-width:2.2; stroke-dasharray:1 4; opacity:1;}
.dd-range{stroke:var(--accent); stroke-width:1.4; stroke-dasharray:2 6; stroke-linecap:round; fill:var(--accent); fill-opacity:.04;}
.dd-maplabel{width:0; height:0;} /* [REMOVAL-236] !important dropped: Leaflet writes the label icon's iconSize [0, 0] on the element itself (G22) */
.dd-maplabel span{position:absolute; transform:translate(-50%,-50%); display:inline-flex; align-items:center; gap:var(--space-1); padding:2px 7px; border-radius:var(--radius-pill);
  background:var(--map-label-bg); color:var(--text-secondary); border:1px solid color-mix(in srgb,var(--text-secondary) 22%,transparent);}
.dd-maplabel .ic{width:11px; height:11px;}
.dd-maplabel b{color:var(--text-primary); font-weight:700;}
/* [REMOVAL-244] .dd-eta-line.is-urgent, .dd-linklbl span.is-viol and .dd-etalbl.is-urgent (--sev-high-ink, a severity hue without its shape) replaced by the data-sev and data-urgent rules (G12, G13) */
.dd-maplabel .shp{width:12px; height:12px;}
/* the pilot link's label: text stays --text-primary on the pill (severity ink as text sits on --surface-0/1 only, G27);
   the violation's severity is its shape and the border in that ink */
.dd-linklbl span[data-sev]{color:var(--text-primary); border-width:1.5px;}
.dd-linklbl span[data-sev="low"]{border-color:var(--sev-low-ink);} .dd-linklbl span[data-sev="medium"]{border-color:var(--sev-medium-ink);}
.dd-linklbl span[data-sev="high"]{border-color:var(--sev-high-ink);} .dd-linklbl span[data-sev="critical"]{border-color:var(--sev-critical-ink);}
.dd-etalbl span[data-urgent]{color:var(--text-primary); border-color:var(--text-primary); font-weight:700;}
.dd-z-far .dd-maplabel{display:none;}

/* drone marker (Airspace Ops .trk + heading pointer + status badge + chip) */
.dd-trk-icon{background:none; border:0;}
.dd-trk{position:relative; width:30px; height:30px; cursor:pointer;}
.dd-trk .trk{position:absolute; inset:0;}
.dd-trk .trk__glyph,.dd-trk__hdg{transition:transform var(--track-dur-turn) linear;}
.dd-trk__hdg{position:absolute; inset:-13px; pointer-events:none;}
.dd-trk__hdg i{position:absolute; left:50%; top:0; margin-left:-5px; width:0; height:0;
  border-left:5px solid transparent; border-right:5px solid transparent; border-bottom:8px solid var(--track-halo);
  filter:drop-shadow(0 0 1.5px var(--dd-hdg-shadow));}
.dd-trk__st{position:absolute; left:-8px; bottom:-8px; width:16px; height:16px; border-radius:var(--radius-round); background:var(--surface-0);
  display:flex; align-items:center; justify-content:center; box-shadow:0 0 0 1px var(--border-strong); font:800 11px/1 var(--font); z-index:2; color:var(--text-primary);}
.dd-trk__st svg{width:10px; height:10px;} /* the flag and the "!" are statuses, not severities: neutral ink, the marker itself carries the severity (G12) */
/* [REMOVAL-258] .dd-trk__st--susp (the "!" in the critical ink) folded into .dd-trk__st: both badges take the neutral ink (G12) */
.dd-trk__chip{position:absolute; top:37px; left:50%; transform:translateX(-50%); pointer-events:none; gap:5px; padding:1px var(--space-2) 1px 6px; font-size:10.5px;}
/* [REMOVAL-212] .dd-trk__chip .shp 9 px dropped: the label chip has no severity word, so its shape takes the 12 px floor (G02) */
.dd-trk__chip .cls{font-family:var(--font-mono); font-size:10px; color:var(--text-secondary); letter-spacing:0;}
.dd-trk__chip .dd-cls-red{font-family:var(--font); font-size:8.5px; color:var(--sev-critical-ink); letter-spacing:.08em;}
.dd-trk__nm{max-width:110px; overflow:hidden; text-overflow:ellipsis;}
.dd-map.dd-z-far .dd-trk:not(.is-sel) .dd-trk__chip{display:none;}
.dd-trk-icon:focus{outline:none;}
.dd-trk-icon:focus-visible .trk{outline:2px solid var(--accent); outline-offset:4px;}
.dd-trk:hover .trk{transform:scale(1.08);}
.dd-trk .trk{transition:transform var(--dur-fast);}
.dd-trk.is-ghost .trk{outline:2px dashed var(--accent); outline-offset:4px;}
.dd-trk.is-ghost .dd-trk__chip{border-color:var(--accent); color:var(--accent);}
.dd-pilot.is-ghost{border-color:var(--accent); border-style:dashed;}
.dd-pilot-icon,.dd-home-icon{background:none; border:0;}
.dd-pilot{width:26px; height:26px; border-radius:var(--radius-round); background:var(--surface-0); border:2px solid var(--text-secondary); color:var(--text-primary);
  display:flex; align-items:center; justify-content:center; box-shadow:var(--track-shadow); cursor:pointer;}
.dd-pilot svg{width:16px; height:16px;}
.dd-pilot--sm{width:20px; height:20px; border-width:1.5px; box-shadow:none; cursor:default;} .dd-pilot--sm svg{width:12px; height:12px;}
.dd-home{width:22px; height:22px; border-radius:var(--radius-sm); background:var(--surface-2); border:1.5px solid var(--text-muted); color:var(--text-secondary);
  display:flex; align-items:center; justify-content:center; box-shadow:var(--track-shadow);}
.dd-home svg{width:13px; height:13px;}
.dd-home--sm{width:18px; height:18px; box-shadow:none;} .dd-home--sm svg{width:11px; height:11px;}

/* map focus (R1-31, G28). dd-focus.js decides, live.js sets the classes: .dd-focus-on on the map while a drone is
   selected or an urgent drone is in view, .dd-focus-sel as well while a drone is selected; is-front, is-alert
   (critical: faded less under a selection, its lines fade) or is-bg on a drone's layers; is-rel, is-breach, is-top
   or is-bg on objects, rings and zones. Faded layers stay drawn and clickable, and pointing at a faded drone shows
   it in full */
.dd-trk,.dd-pilot,.dd-home,.dd-map path:is(.trail,.dd-pilot-link,.dd-eta-line,.dd-range,.dd-obj,.dd-zone,.dd-ring){transition:opacity var(--dur-base) var(--ease);}
.dd-focus-on .dd-trk-icon.is-bg:not(:hover):not(:focus-visible) .dd-trk,
.dd-focus-on :is(.dd-pilot-icon,.dd-home-icon).is-bg:not(:hover) > *{opacity:var(--dd-focus-fade);}
/* a selected drone dims every other drone (owner decision 4 Oct 2026); a critical one fades only to --dd-focus-fade,
   which keeps 3:1, and keeps its name */
.dd-focus-sel .dd-trk-icon.is-bg:not(:hover):not(:focus-visible) .dd-trk,
.dd-focus-sel :is(.dd-pilot-icon,.dd-home-icon).is-bg:not(:hover) > *{opacity:var(--dd-focus-fade-select);}
.dd-focus-sel .dd-trk-icon.is-alert:not(:hover):not(:focus-visible) .dd-trk,
.dd-focus-sel :is(.dd-pilot-icon,.dd-home-icon).is-alert:not(:hover) > *{opacity:var(--dd-focus-fade);}
.dd-focus-on .dd-trk-icon.is-bg:not(:hover):not(:focus-visible) .dd-trk__chip{display:none;}
.dd-map.dd-focus-on.dd-z-far .dd-trk-icon.is-front .dd-trk__chip{display:inline-flex;}
.dd-focus-on path:is(.trail,.dd-pilot-link,.dd-eta-line,.dd-range):is(.is-bg,.is-alert){opacity:var(--dd-focus-fade-line);}
.dd-focus-on .dd-maplabel:is(.is-bg,.is-alert),.dd-focus-on :is(.dd-ring-lbl,.dd-zlabel,.dd-olabel).is-bg{display:none;}
.dd-focus-on path:is(.dd-obj,.dd-zone,.dd-ring).is-bg{opacity:var(--dd-focus-fade-area);}
.dd-focus-on path:is(.dd-obj,.dd-zone).is-rel:not(.is-sel){stroke-width:2.6;}
.dd-focus-on path:is(.dd-obj,.dd-zone).is-breach:not(.is-sel){stroke-width:3.2;}
.dd-focus-on path.dd-ring.is-breach{stroke-dasharray:none; stroke-width:2.2; stroke-opacity:1;}
.dd-map.dd-focus-on .dd-ring-lbl.is-rel{display:block;}
.dd-focus-on .dd-ring-lbl.is-breach span{opacity:1; font-weight:700;}

/* ---- drones the live filters hide: a neutral dot, not a severity marker (R1-31, DD.detail / live.js refreshIcon) ---- */
.dd-trk-icon--dot{width:14px; height:14px;}
.dd-trk--dot{display:block; width:14px; height:14px;}
.dd-dot{display:block; width:10px; height:10px; margin:auto; position:relative; top:2px; left:2px; border-radius:var(--radius-round); background:var(--text-muted); border:1.5px solid var(--surface-0); opacity:.75; cursor:pointer; transition:opacity var(--dur-fast), background var(--dur-fast);}
/* drones merged into a group bubble (dd-edge.js): the marker stays, unseen, so the drone can leave the group without a rebuild */
.dd-trk-icon--grouped{display:none;}
.dd-cluster{display:flex; align-items:center; justify-content:center; position:relative; width:36px; height:36px; border-radius:var(--radius-round); cursor:pointer;
  background:var(--surface-0); border:1.5px solid var(--border-strong); box-shadow:var(--elev-2); color:var(--text-primary); font:700 12px var(--font-mono);}
.dd-cluster .shp{position:absolute; top:calc(var(--space-1) * -1); right:calc(var(--space-1) * -1); width:14px; height:14px; box-shadow:0 0 0 1px var(--surface-0); border-radius:var(--radius-round); background:var(--surface-0);}
.dd-cluster-icon:hover .dd-cluster,.dd-cluster-icon:focus-visible .dd-cluster{border-color:var(--accent);}
.dd-cluster-icon:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--radius-round);}
/* edge wedges for the red and orange drones outside the view (dd-edge.js) */
.dd-wedges{position:absolute; inset:0; pointer-events:none; z-index:var(--z-dd-panel);}
.dd-wedge{position:absolute; transform:translate(-50%,-50%); display:inline-flex; align-items:center; gap:var(--space-1); height:26px; padding:0 var(--space-1) 0 var(--space-2); border-radius:var(--radius-pill); pointer-events:auto; cursor:pointer;
  background:var(--surface-0); border:1.5px solid var(--c); color:var(--text-primary); font:700 11px var(--font-mono); white-space:nowrap; box-shadow:var(--elev-2);}
.dd-wedge .shp{width:12px; height:12px;}
.dd-wedge .ic{width:15px; height:15px; color:var(--c); transform:rotate(var(--a));}
.dd-wedge[data-sev="high"]{--c:var(--sev-high-ink);} .dd-wedge[data-sev="critical"]{--c:var(--sev-critical-ink);}
.dd-wedge:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.dd-chip-float{position:absolute; left:50%; bottom:var(--space-7); transform:translateX(-50%); display:inline-flex; align-items:center; gap:var(--space-2); padding:var(--space-1) var(--space-1) var(--space-1) var(--space-3); font-size:12px; color:var(--text-secondary); z-index:var(--z-dd-panel);}
.dd-chip-float[hidden]{display:none;}
.dd-chip-float b{color:var(--text-primary);}
.dd-trk-icon--dot:hover .dd-dot{opacity:1; background:var(--text-secondary);}
.dd-trk-icon--dot:focus-visible .dd-dot{outline:2px solid var(--accent); outline-offset:2px;}
.dd-dot--legend{display:inline-block; margin:0 var(--space-1) 0 0; flex:0 0 10px; cursor:default;}

/* ---- map detail level (R1-31): dd-lvl-essential | dd-lvl-standard | dd-lvl-all on the map container, set by dd-detail.js.
   All draws everything, as before. Essential and Standard keep objects and zones as quiet outlines, draw a ring only where
   a drone breaks it, and name an area only while it is involved (is-hit breaks it now, is-rel is what the focus points at). ---- */
:is(.dd-lvl-essential,.dd-lvl-standard) path.dd-ring:not(.is-hit):not(.is-breach){display:none;}
:is(.dd-lvl-essential,.dd-lvl-standard) .dd-ring-lbl:not(.is-hit):not(.is-breach){display:none;}
:is(.dd-lvl-essential,.dd-lvl-standard) path:is(.dd-obj,.dd-zone):not(.is-hit):not(.is-rel){stroke-opacity:.5; fill-opacity:.35;}
:is(.dd-lvl-essential,.dd-lvl-standard) :is(.dd-olabel,.dd-zlabel):not(.is-hit):not(.is-rel){display:none;}
/* drone names: Standard names the high and critical drones, Essential only the critical ones; the selected and the pointed-at drone always */
.dd-lvl-standard .dd-trk:not(.is-sel):not(:hover):has(.trk:is([data-sev="low"],[data-sev="medium"])) .dd-trk__chip{display:none;}
.dd-lvl-essential .dd-trk:not(.is-sel):not(:hover):has(.trk:not([data-sev="critical"])) .dd-trk__chip{display:none;}
/* sensor coverage: the mask outside it only while the view is not fully covered (dd-cov-attn); stations that cover fine stay hidden */
:is(.dd-lvl-essential,.dd-lvl-standard) path.cov--covering{display:none;}
:is(.dd-lvl-essential,.dd-lvl-standard):not(.dd-cov-attn) path.cov--mask{display:none;}
:is(.dd-lvl-essential,.dd-lvl-standard) .dd-station-icon:has(.dd-station[data-class="covering"]){display:none;}
.dd-lvl-essential .dd-station-icon{display:none;}
/* the Map detail control at the top of the legend */
.dd-detlvl{border:0; margin:0 0 var(--space-2); padding:0; min-width:0;}
.dd-detlvl legend{padding:0; margin:0 0 var(--space-1);}
.dd-detlvl__seg{display:grid; grid-template-columns:repeat(3, 1fr); border:1px solid var(--border-default); border-radius:var(--radius-md); overflow:hidden; background:var(--surface-sunken);}
.dd-detlvl__seg button{height:32px; border:0; border-right:1px solid var(--border-subtle); background:none; color:var(--text-secondary); font-size:12px; font-weight:700;}
.dd-detlvl__seg button:last-child{border-right:0;}
.dd-detlvl__seg button:hover{background:var(--surface-1); color:var(--text-primary);}
.dd-detlvl__seg button[aria-pressed="true"]{background:var(--accent-soft); color:var(--accent);}
.dd-detlvl__seg button:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;}
.dd-detlvl__custom{display:flex; align-items:center; gap:var(--space-2); margin-top:var(--space-2); padding:var(--space-1) var(--space-2); border-radius:var(--radius-md); background:var(--status-warn-bg); border:1px solid var(--status-warn-bd); color:var(--text-primary); font-size:11.5px;}
.dd-detlvl__custom .ic{width:13px; height:13px; flex:0 0 13px; color:var(--status-warn-fg);}
.dd-detlvl__custom button{margin-left:auto; border:0; background:none; padding:0; color:var(--accent); font-weight:700; font-size:11.5px; text-decoration:underline; text-underline-offset:2px;}
.dd-detlvl__list{margin:var(--space-2) 0 0; padding:0; list-style:none; font-size:11.5px; color:var(--text-secondary);}
.dd-detlvl__list li{display:flex; align-items:center; gap:var(--space-2);}
.dd-detlvl__list li::before{content:""; width:5px; height:5px; border-radius:var(--radius-round); background:var(--text-muted); flex:0 0 5px;}
#dd-t-legend.is-custom::after{content:""; position:absolute; top:4px; right:4px; width:7px; height:7px; border-radius:var(--radius-round); background:var(--status-warn-fg);}
/* is-top: the area behind a front drone's most severe violation (owner decision 3 Oct 2026): the strongest outline
   in its own colour, its label framed in that colour (700: the heaviest JetBrains Mono face vendored) */
.dd-focus-on path:is(.dd-obj,.dd-zone).is-top:not(.is-sel){stroke-width:4.4;}
.dd-focus-on path.dd-ring.is-top{stroke-width:3.4;}
.dd-focus-on :is(.dd-zlabel,.dd-ring-lbl).is-top span,.dd-focus-on .dd-olabel.is-top{box-shadow:0 0 0 1.5px currentColor; font-weight:700;}
@media (prefers-reduced-motion: reduce){
  .dd-trk,.dd-pilot,.dd-home,.dd-map path:is(.trail,.dd-pilot-link,.dd-eta-line,.dd-range,.dd-obj,.dd-zone,.dd-ring){transition:none;}
}
/* label decluttering (G28): dd-declutter.js hides the lower-ranked of two colliding labels; hidden, not removed, so
   it keeps its box for the next pass. Pointing at or focusing a drone shows its name chip */
.dd-map .dd-declut{visibility:hidden;}
.dd-map .dd-trk-icon:is(:hover,:focus-visible) .dd-trk__chip.dd-declut{visibility:visible;}

/* ------------------------------------------------------------ 4 live view */
.dd-live-view{position:absolute; inset:0; overflow:hidden;}
/* [REMOVAL-103] .dd-evbar dropped from this rule: the event summary bar (.dd-evsum, section 14) replaced the card strip */
.dd-live-view > .map-panel,.dd-live-view > .tool-rail,.dd-live-view > .dd-evsum,.dd-live-view > .dd-hover{z-index:var(--z-dd-panel);}
.dd-live-view .map-panel{background:color-mix(in srgb,var(--surface-0) 94%,transparent); backdrop-filter:blur(10px); border-color:var(--border-subtle);}
/* panel title, as the event queue's: the left panel, the event summary bar and the track details take their
   accessible name from it (aria-labelledby) */
.dd-ptitle{margin:0; display:flex; align-items:center; gap:var(--space-2); min-width:0; font-size:14.5px; font-weight:800; line-height:1.25; color:var(--text-primary); white-space:nowrap;}
.dd-ptitle .ic{width:16px; height:16px; flex:0 0 16px; color:var(--text-secondary);}
.dd-ptitle > span{min-width:0; overflow:hidden; text-overflow:ellipsis;}

/* left panel */
.dd-lp{position:absolute; top:var(--dd-gap); left:var(--dd-gap); bottom:var(--dd-gap); width:var(--dd-lp-w); display:flex; flex-direction:column; overflow:hidden;}
.dd-lp__hd{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2); padding:var(--space-2) var(--space-3); border-bottom:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-lp__shown{display:inline-flex; align-items:center; gap:var(--space-2); font-size:12px; color:var(--text-secondary); white-space:nowrap;}
.dd-lp__shown[hidden]{display:none;}
.dd-lp__shown button{border:0; background:none; padding:0 var(--space-1); color:var(--accent); font-weight:700; font-size:12px; text-decoration:underline; text-underline-offset:2px; cursor:pointer;}
.dd-lp__kpis{display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:6px; padding:10px 10px var(--space-2); border-bottom:1px solid var(--border-subtle);}
.dd-kpi{position:relative; background:var(--surface-1); border:1px solid var(--border-subtle); border-radius:var(--radius-md); padding:6px var(--space-2) 5px;}
.dd-kpi b{display:block; font:700 18px/1.1 var(--font-mono); color:var(--text-primary);}
.dd-kpi span{font-size:9.5px; font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--text-muted);}
.dd-kpi .shp{position:absolute; top:8px; right:8px;}
/* [REMOVAL-427] .dd-kpi--live (the Live tile) and .dd-tlpick (the Risk level chips in Filters) dropped with those controls: the tiles are the risk filter now */
.dd-lp__kpis[hidden]{display:none;}
.dd-lp__kpis--cov{grid-template-columns:minmax(0,1fr); padding-top:0;}
.dd-lp__kpis--3{padding-bottom:var(--space-2);}
.dd-lp__kpis--3 .dd-kpi{padding:var(--space-2) var(--space-3) var(--space-1); text-align:left; font:inherit; cursor:pointer; color:inherit;}
.dd-lp__kpis--3 .dd-kpi:hover{border-color:var(--border-strong);}
.dd-lp__kpis--3 .dd-kpi:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.dd-kpi[aria-pressed="false"]{border-style:dashed; background:none; opacity:.6;}
.dd-kpi[aria-pressed="false"] b{text-decoration:line-through; color:var(--text-muted);}
.dd-kpi[data-zero="true"] b{color:var(--text-disabled);}
.dd-kpi[data-tl="red"] b{color:var(--sev-critical-ink);} .dd-kpi[data-tl="orange"] b{color:var(--sev-high-ink);} .dd-kpi[data-tl="green"] b{color:var(--sev-low-ink);}
/* coverage of the visible map (R1-31): system status colours with a shape icon, never a severity hue */
.dd-covchip{grid-column:1 / -1; display:flex; align-items:center; gap:7px; min-height:26px; padding:var(--space-1) 9px; border-radius:var(--radius-md);
  background:var(--surface-1); border:1px solid var(--border-subtle); color:var(--text-primary); font-size:12px; font-weight:600; line-height:1.3;}
.dd-covchip .ic{width:14px; height:14px; flex:0 0 14px; color:var(--text-muted);}
.dd-covchip[data-state="full"]{background:var(--status-ok-bg); border-color:var(--status-ok-bd);} .dd-covchip[data-state="full"] .ic{color:var(--status-ok-fg);}
.dd-covchip[data-state="partial"]{background:var(--status-warn-bg); border-color:var(--status-warn-bd);} .dd-covchip[data-state="partial"] .ic{color:var(--status-warn-fg);}
.dd-covchip[data-state="none"]{background:var(--status-error-bg); border-color:var(--status-error-bd);} .dd-covchip[data-state="none"] .ic{color:var(--status-error-fg);}
.dd-covchip[data-state="stale"]{border-style:dashed;}
.dd-lp__search{padding:10px 10px 6px;}
.dd-lp__search .searchbox{height:36px; background:var(--surface-sunken);}
.dd-lp__search input::-webkit-search-cancel-button{filter:grayscale(1);}
.dd-filters{margin:0 10px 6px; border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-filters > summary{list-style:none; display:flex; align-items:center; gap:var(--space-2); padding:7px 10px; cursor:pointer; font-size:12.5px; font-weight:700; color:var(--text-secondary);}
.dd-filters > summary::-webkit-details-marker{display:none;}
.dd-filters > summary:hover{color:var(--text-primary);}
.dd-filters__chev{margin-left:auto; width:14px; height:14px; transition:transform var(--dur-fast);}
.dd-filters[open] .dd-filters__chev{transform:rotate(180deg);}
.dd-filters__n{min-width:18px; height:18px; padding:0 5px; border-radius:9px; background:var(--accent); color:var(--on-accent); font:700 10.5px/18px var(--font-mono); text-align:center;}
.dd-filters__bd{padding:var(--space-1) 10px 10px; border-top:1px solid var(--border-subtle);}
.dd-frow{margin:var(--space-2) 0 var(--space-1);}
.dd-frow .form-label{display:block; margin-bottom:5px;}
.dd-frow--checks{display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:var(--space-1);}
.dd-f-reset{margin-left:auto;}
.dd-grid2{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:10px;}
.dd-grid2 > *{min-width:0;}
/* [REMOVAL-239] .dd-grid3 dropped: no template or script uses it (G29) */
.dd-filters .field{margin-bottom:0;}
.dd-filters .form-select{height:32px; font-size:12.5px;}
.dd-lp__tabs{margin:var(--space-1) 0 0; padding:0 6px;}
.dd-lp__tabs .tab{padding:.55rem .7rem; font-size:12.5px;}
.dd-lp__tabs .tab .ic{width:14px; height:14px;}
.dd-lp__tabs .win__count{margin-left:2px; padding:1px 7px;}
/* [REMOVAL-245] .win__count.is-hot (critical ink as text, no shape) replaced: red-listed drones in the air are critical items, so the count is a critical risk chip in miniature, text in --risk-critical-fg and the ⬣ shape in the critical ink (G12, G13) */
.dd-lp__tabs .win__count[data-hot]{display:inline-flex; align-items:center; gap:var(--space-1); background:var(--risk-critical-bg); color:var(--risk-critical-fg);}
.dd-lp__tabs .win__count[data-hot]::before{content:""; width:.62rem; height:.62rem; background:var(--sev-critical-ink); clip-path:var(--shape-critical);}
.dd-lp__body{flex:1; min-height:0; overflow:auto; padding:var(--space-1) 6px 10px;} .dd-lp .dd-lp__body:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* inset, as the event queue's list: the panel clips an outer ring */
.dd-empty-sm{padding:14px; color:var(--text-muted); font-size:12.5px; display:flex; gap:var(--space-2); align-items:center;}
.dd-empty{margin:14px 6px; padding:22px 14px;}
.dd-empty > .ic{width:26px; height:26px; color:var(--text-disabled); margin-bottom:6px;}
.dd-empty p{margin:0; font-size:12.5px;}
/* threat tree */
.dd-tg{margin-top:6px;}
.dd-tg__hd{display:flex; align-items:center; gap:7px; width:100%; padding:6px var(--space-2); border:0; background:none; border-radius:7px;
  font-size:11px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); text-align:left;}
button.dd-tg__hd:hover{background:var(--surface-1); color:var(--text-secondary);}
.dd-tg__hd b{margin-left:auto; font:700 11px var(--font-mono); color:var(--text-secondary); background:var(--surface-2); border-radius:9px; padding:1px 7px; letter-spacing:0;}
.dd-tg[data-tl="red"] > .dd-tg__hd{color:var(--sev-critical-ink);}
.dd-tg[data-tl="orange"] > .dd-tg__hd{color:var(--sev-high-ink);}
.dd-tg[data-tl="green"] > .dd-tg__hd{color:var(--sev-low-ink);}
.dd-tg__fold{display:flex; align-items:center; gap:var(--space-2); width:100%; margin:2px 0; padding:var(--space-2); border:1px dashed var(--border-default); border-radius:var(--radius-md); background:none; color:var(--text-secondary); font-size:12.5px; text-align:left; cursor:pointer;}
.dd-tg__fold:hover{background:var(--surface-1); color:var(--text-primary);}
.dd-tg__fold:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;}
.dd-tg__fold .ic{width:14px; height:14px; color:var(--text-muted);}
.dd-tg__fold b{margin-left:auto; font:700 11px var(--font-mono); color:var(--text-muted);}
.dd-tg__chev{width:13px; height:13px; color:var(--text-muted);}
.dd-tg__list{list-style:none; margin:2px 0 0; padding:0;}
.dd-tg__none{padding:6px 10px 6px 30px; font-size:12px; color:var(--text-disabled);}
.dd-trow{display:flex; align-items:stretch; border-radius:9px; margin:2px 0; position:relative;}
.dd-trow:hover{background:var(--surface-1);}
.dd-trow.is-sel{background:var(--accent-soft); box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent) 45%,transparent);}
.dd-trow__main{flex:1; min-width:0; display:flex; align-items:center; gap:10px; padding:7px var(--space-1) 7px var(--space-2); border:0; background:none; text-align:left; color:inherit; border-radius:9px;}
.dd-trow__bd{flex:1; min-width:0; display:flex; flex-direction:column; gap:1px;}
/* [REMOVAL-429] .dd-trow__t, __s and __m (name line, serial line, metric line) replaced by .dd-trow__why and .dd-trow__sub: the row leads with the reason */
.dd-trow__why{font-size:13px; font-weight:700; line-height:1.3; color:var(--text-primary); white-space:normal; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
.dd-trow__sub{display:flex; flex-wrap:wrap; align-items:center; gap:2px var(--space-2); font-size:11.5px; color:var(--text-secondary);}
.dd-trow__sub .dd-mono{font-size:11px; color:var(--text-secondary);}
.dd-trow__eta{color:var(--text-secondary); white-space:nowrap;} .dd-trow__eta[data-urgent]{color:var(--text-primary); font-weight:800;} /* [REMOVAL-246] .dd-trow__eta.is-urgent (--sev-high-ink) replaced: urgency is weight and contrast, never a severity hue (G12, G13) */
.dd-trow__sev{display:inline-flex; align-items:center; gap:var(--space-1); font:700 13px var(--font-mono);}
.dd-trow__more{width:28px; border:0; background:none; color:var(--text-muted); border-radius:7px; margin:var(--space-1) 2px; opacity:.6;}
.dd-trow:hover .dd-trow__more,.dd-trow__more:focus-visible{opacity:1;}
.dd-trow__more:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-trow__more .ic{width:16px; height:16px;}
.dd-mini{--c:var(--sev-low); --ink:var(--sev-low-ink); width:26px; height:26px; flex:0 0 26px; border-radius:var(--radius-md); display:flex; align-items:center; justify-content:center;
  background:var(--c); border:1.5px solid var(--track-halo); color:var(--track-glyph-on-fill);}
.dd-mini svg{width:16px; height:16px; fill:currentColor;}
.dd-mini[data-sev="medium"]{--c:var(--sev-medium); --ink:var(--sev-medium-ink);} .dd-mini[data-sev="high"]{--c:var(--sev-high); --ink:var(--sev-high-ink);}
.dd-mini[data-sev="critical"]{--c:var(--sev-critical); --ink:var(--sev-critical-ink);}
.dd-mini[data-coop="false"]{background:var(--track-hollow-fill); border:2px dashed var(--ink); color:var(--ink);}
.dd-listchip{white-space:nowrap; display:inline-flex; align-items:center; height:17px; padding:0 6px; border-radius:4px; font-size:9px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  border:1px solid var(--border-default); color:var(--text-secondary); background:var(--surface-2); flex:0 0 auto;}
.dd-listchip[data-list="red"]{background:var(--risk-critical-bg); border-color:var(--risk-critical-bd); color:var(--risk-critical-fg);}
.dd-listchip[data-list="flagged"]{background:var(--risk-high-bg); border-color:var(--risk-high-bd); color:var(--risk-high-fg);}
.dd-listchip[data-list="white"]{background:var(--surface-0); border-color:var(--border-strong); color:var(--text-primary);}
.dd-listchip[data-list="green"]{background:var(--risk-low-bg); border-color:var(--risk-low-bd); color:var(--risk-low-fg);}
.dd-rrow{margin:2px 0;}
.dd-rrow__main{display:flex; align-items:center; gap:var(--space-2); width:100%; padding:7px 10px; border:0; background:none; border-radius:9px; text-align:left; color:inherit;}
button.dd-rrow__main:hover{background:var(--surface-1);}
.dd-rrow__bd{flex:1; min-width:0; display:flex; flex-direction:column; font-size:12px; color:var(--text-secondary);}
.dd-rrow__bd b{font-size:12.5px; color:var(--text-primary);}
.dd-rrow__r{font-size:11px; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}

/* [REMOVAL-102] Event bar card strip (.dd-evbar, .dd-evbar__*, .dd-evc*) replaced by the event summary bar and the
   event queue (section 14): the strip held at most 40 cards of 320 px, clipping rule titles in es, fr and nl (G26) */

/* tools, legend, chips */
.dd-tools{position:absolute; top:calc(var(--dd-gap) + 66px); right:var(--dd-gap); transition:right var(--dur-base) var(--ease);}
.dd-tools button[aria-pressed="true"],.dd-tools button.is-active{background:var(--accent-soft); color:var(--accent);}
.dd-tools .ic{width:18px; height:18px;}
/* up to two 212 px columns in the map's room left of the tool rail; they stack, and the panel scrolls, when they no
   longer fit side by side; neither a column nor the panel gets narrower than its longest word */
.dd-legend{position:absolute; top:calc(var(--dd-gap) + 66px); right:calc(var(--dd-gap) + 52px); width:clamp(236px, 100% - var(--dd-lp-w) - 3 * var(--dd-gap) - 52px, 464px); min-width:min-content; padding:10px var(--space-3); font-size:12px; color:var(--text-secondary); transition:right var(--dur-base) var(--ease);
  max-height:calc(100% - 2 * var(--dd-gap) - 150px); overflow-y:auto; display:flex; flex-wrap:wrap; align-items:flex-start; gap:var(--space-2) var(--space-4);}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-legend{width:clamp(236px, 100% - var(--dd-lp-w) - var(--dd-detail-w) - 4 * var(--dd-gap) - 52px, 464px);}
.dd-legend__col{flex:1 1 144px;}
.dd-legend__switch{cursor:pointer; color:var(--text-primary);}
.dd-legend__cap{font-size:9.5px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-muted); margin:var(--space-2) 0 var(--space-1);}
.dd-legend__cap:first-child{margin-top:0;}
.dd-legend__row{display:flex; align-items:center; gap:var(--space-2); padding:2px 0;}
.dd-legend__row .dd-mono{margin-left:auto; color:var(--text-muted); font-size:11px;}
.dd-lg-trk{width:16px; height:16px; border-radius:5px; background:var(--sev-medium); border:1.5px solid var(--track-halo); flex:0 0 16px;}
.dd-lg-trk[data-coop="false"]{background:var(--track-hollow-fill); border:2px dashed var(--sev-medium-ink);}
.dd-lg-ring{width:18px; height:18px; border-radius:var(--radius-round); border:1.5px dashed var(--zone-protected-stroke); opacity:.8; flex:0 0 18px;}
.dd-lg-trk--faded{opacity:var(--dd-focus-fade-select);} /* [REMOVAL-371] opacity:var(--dd-focus-fade) replaced: the swatch shows how far a selection dims the other drones */
.dd-histchip{position:absolute; top:calc(var(--dd-gap) + 66px); left:calc(var(--dd-lp-w) + 2 * var(--dd-gap)); display:flex; align-items:center; gap:10px; padding:6px 6px 6px var(--space-3); font-size:12px; color:var(--text-secondary); z-index:var(--z-dd-panel);}
.dd-histchip b{color:var(--text-primary);}
.dd-hl-d,.dd-hl-p{display:inline-block; width:9px; height:9px; border-radius:var(--radius-round); margin:0 3px 0 6px; vertical-align:-1px;}
.dd-hl-d{background:color-mix(in srgb,var(--track-halo) 45%,transparent);} .dd-hl-p{border:1.5px solid var(--accent);}

/* detail panel */
.dd-detail{position:absolute; top:calc(var(--dd-gap) + 66px); right:var(--dd-gap); bottom:var(--dd-gap); width:var(--dd-detail-w); display:flex; flex-direction:column; overflow:hidden; z-index:calc(var(--z-dd-panel) + 1);}
.dd-live-view.has-detail .dd-tools{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap));}
.dd-live-view.has-detail .dd-legend{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap) + 52px);}
.dd-live-view.has-detail .dd-statusbar{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap));}
.dd-detail__hd{padding:var(--space-3) var(--space-3) 10px var(--space-4); border-bottom:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-detail__top{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2); margin-bottom:var(--space-2);}
.dd-detail__title{display:flex; align-items:center; gap:10px;}
.dd-detail__title > div{flex:1; min-width:0; display:flex; flex-direction:column;}
.dd-detail__title b{font-size:15.5px; font-weight:800; line-height:1.25;}
.dd-detail__title .dd-mono{font-size:12px; color:var(--text-secondary);}
.dd-detail__shape{width:18px; height:18px;}
.dd-detail__chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; align-items:center;}
.dd-detail__src{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:var(--space-2);}
.dd-seen{margin-left:auto; font-size:11px; font-family:var(--font-mono); font-variant-numeric:tabular-nums; color:var(--text-secondary);} .dd-seen.live-ink{color:var(--live-ink);} /* lime only while the track is live (G25) */
.dd-rid-no{font-weight:700; color:var(--status-warn-fg);} /* no Remote ID is a state of the drone (status colour); its violation keeps severity ink and shape under Violations (G12) */
.dd-coop{font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; padding:2px var(--space-2); border-radius:5px; border:1.5px solid var(--text-secondary); color:var(--text-secondary);}
.dd-coop[data-coop="false"]{border-style:dashed;}
.dd-detail__closed{margin:10px var(--space-3) 0;}
.dd-detail__acts{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--space-1); padding:var(--space-2) 10px; border-bottom:1px solid var(--border-subtle);}
.dd-act{display:flex; flex-direction:column; align-items:center; gap:3px; padding:7px 2px 6px; border-radius:var(--radius-md); border:1px solid transparent; background:none; color:var(--text-secondary); font-size:10.5px; font-weight:700;}
.dd-act .ic{width:18px; height:18px;}
.dd-act:hover:not(:disabled){background:var(--surface-1); color:var(--text-primary); border-color:var(--border-subtle);}
.dd-act.is-on{color:var(--accent); background:var(--accent-soft);}
.dd-act.is-primary{color:var(--accent);}
.dd-act:disabled{opacity:.4; cursor:not-allowed;}
.dd-detail__bd{flex:1; overflow:auto; padding:var(--space-1) var(--space-4) var(--space-4);}
.dd-sec{padding:var(--space-3) 0 var(--space-1); border-bottom:1px solid var(--border-subtle);}
.dd-sec:last-child{border-bottom:0;}
.dd-sec__cap{font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-muted); margin:0 0 var(--space-2);}
/* the evidence card of the track details (live declutter): why it matters, what happens next, what you can do; the rest is folded */
.dd-why{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--space-2);}
.dd-why li{display:flex; align-items:flex-start; gap:var(--space-2); padding:var(--space-2); border-radius:var(--radius-md); background:var(--surface-1); border:1px solid var(--border-subtle);}
.dd-why li > .shp{margin-top:var(--space-1); flex:0 0 12px; width:12px; height:12px;}
.dd-why__bd{flex:1; min-width:0; display:flex; flex-direction:column; font-size:12.5px;}
.dd-why__bd b{font-weight:700; line-height:1.3;}
.dd-why__bd span{font-size:11px; color:var(--text-muted);}
.dd-why .dd-why__ok{display:block; border-style:dashed; font-size:12.5px; color:var(--text-muted);}
.dd-figs{display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:var(--space-2); margin-bottom:var(--space-2);}
.dd-fig{padding:var(--space-2); border-radius:var(--radius-md); background:var(--surface-1); border:1px solid var(--border-subtle);}
.dd-fig b{display:block; font:700 17px/1.2 var(--font-mono); color:var(--text-primary);}
.dd-fig span{display:block; margin-top:var(--space-1); font-size:10.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:var(--text-muted);}
.dd-fig small{display:block; font-size:11px; color:var(--text-secondary);}
.dd-actrow__main{display:flex; gap:var(--space-2); margin-bottom:var(--space-2);}
.dd-actrow__main:empty{display:none;}
.dd-actrow__main .btn{flex:1;}
.dd-sec .dd-detail__acts{padding:0; border-bottom:0;}
.dd-fold{border-bottom:1px solid var(--border-subtle);}
.dd-fold > summary{list-style:none; display:flex; align-items:center; gap:var(--space-2); padding:var(--space-3) 0; cursor:pointer; font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-muted);}
.dd-fold > summary::-webkit-details-marker{display:none;}
.dd-fold > summary:hover{color:var(--text-secondary);}
.dd-fold > summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.dd-fold > summary small{margin-left:auto; font-size:10.5px; font-weight:600; letter-spacing:0; text-transform:none; color:var(--text-muted);}
.dd-fold > summary .ic{width:13px; height:13px;}
.dd-fold[open] > summary .ic{transform:rotate(180deg);}
.dd-fold > div{padding:0 0 var(--space-3);}
.dd-kv{display:grid; grid-template-columns:auto 1fr; gap:5px var(--space-3); font-size:12.5px;}
.dd-kv > span:nth-child(odd){color:var(--text-muted);}
.dd-kv > span:nth-child(even){text-align:right; font-family:var(--font-mono); font-variant-numeric:tabular-nums; color:var(--text-primary);}
.dd-kv small{color:var(--text-muted); font-size:10.5px;}
/* values first: each value keeps its line and the keys wrap; a narrow card breaks a value only between its
   parts, never at the hyphens of a Dutch date */
.dd-kv--values{grid-template-columns:minmax(min-content, 1fr) auto;}
.dd-kv__part{white-space:nowrap;}
.dd-viol{font-weight:700;} /* [REMOVAL-214] color:var(--sev-critical-ink) dropped: a violation takes its own severity's ink and shape (.sev-ink, owner decision 2 Oct 2026, G04) */
.dd-timeline{list-style:none; margin:0; padding:0 0 0 var(--space-1);}
.dd-tl-item{display:flex; gap:10px; padding:var(--space-1) 0 var(--space-2); position:relative;}
.dd-tl-item::before{content:""; position:absolute; left:5px; top:18px; bottom:-2px; width:1px; background:var(--border-default);}
.dd-tl-item:last-child::before{display:none;}
.dd-tl-dot{flex:0 0 12px; padding-top:3px;}
.dd-tl-item > div{display:flex; flex-direction:column; font-size:12.5px;}
/* [REMOVAL-215] .dd-timeline .dd-viol text-primary, critical items in critical ink: every item takes its own severity's ink (G04) */
.dd-eta-row{display:flex; align-items:center; gap:var(--space-2); padding:var(--space-1) 0; font-size:12.5px;}
.dd-eta-row .ic{color:var(--text-muted);}
.dd-eta-row span:nth-of-type(1){flex:1;}
.dd-eta-row[data-urgent] b{padding:0 6px; border:1px solid var(--text-primary); border-radius:var(--radius-pill);} .dd-eta-row[data-urgent] .ic{color:var(--text-primary);} /* [REMOVAL-247] .dd-eta-row.is-urgent (--sev-high-ink) replaced: an urgent ETA is outlined in the text colour, never a severity hue (G12, G13) */
.dd-evrow{display:flex; align-items:center; gap:9px; padding:7px var(--space-2) 7px var(--space-3); border-radius:var(--radius-md); background:var(--surface-1); margin-bottom:6px;}
.dd-evrow > div{flex:1; min-width:0; display:flex; flex-direction:column; font-size:12.5px;}

/* hover card (FS-53) */
.dd-hover{position:absolute; width:286px; background:var(--surface-0); border:1px solid var(--border-default); border-radius:var(--radius-md); box-shadow:var(--elev-4); pointer-events:none; overflow:hidden; z-index:var(--z-window);}
.dd-hover__hd{display:flex; align-items:center; gap:9px; padding:9px 10px 9px 14px; background:var(--surface-1); border-bottom:1px solid var(--border-subtle);}
.dd-hover__hd .shp{width:13px; height:13px;}
.dd-hover__id{flex:1; min-width:0; display:flex; flex-direction:column; line-height:1.3;}
.dd-hover__id b{font-size:13.5px;}
.dd-hover__id .dd-mono{font-size:11px; color:var(--text-secondary);}
.dd-hover__kv{display:grid; grid-template-columns:auto 1fr; gap:3px 10px; padding:9px var(--space-3); font-size:12px;}
.dd-hover__kv > span:nth-child(odd){color:var(--text-muted);}
.dd-hover__kv > span:nth-child(even){text-align:right; font-family:var(--font-mono); font-variant-numeric:tabular-nums;}
.dd-hover__kv small{color:var(--text-muted); font-size:9.5px;}
/* [REMOVAL-216] critical tint (6 % --sev-critical) and critical ink dropped: each violation takes its own severity's ink
   and shape on the card's neutral --surface-1 (G04); severity ink as text stays on --surface-0/1 (G27) */
.dd-hover__viol{list-style:none; margin:0; padding:var(--space-2) var(--space-3) 9px; border-top:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-hover__viol li{display:flex; align-items:center; gap:7px; font-size:12px; font-weight:700; padding:1px 0;}
.dd-hover__ok{padding:7px var(--space-3) 9px; border-top:1px solid var(--border-subtle); font-size:12px; color:var(--status-ok-fg);} /* all clear is a status, not a low severity (G12) */
.dd-hover__foot{padding:6px var(--space-3) var(--space-2); font-size:11px; color:var(--text-muted); border-top:1px dashed var(--border-default);}

/* context menu (FS-54 / FS-42) */
.dd-cm{position:fixed; z-index:var(--z-dd-cm); min-width:236px; max-width:300px; background:var(--surface-0); border:1px solid var(--border-default); border-radius:var(--radius-md); box-shadow:var(--elev-4); padding:5px;}
.dd-cm__hd{display:flex; align-items:center; gap:7px; padding:7px 9px var(--space-2); margin-bottom:3px; border-bottom:1px solid var(--border-subtle); font-size:12.5px; flex-wrap:wrap;}
.dd-cm__hd .dd-mono{font-size:11px; color:var(--text-muted); width:100%; padding-left:18px;}
.dd-cm__hd .ic{color:var(--text-secondary);}
.dd-cm__item{display:flex; align-items:center; gap:10px; width:100%; padding:7px 9px; border:0; background:none; border-radius:var(--radius-sm); font-size:13px; color:var(--text-primary); text-align:left;}
.dd-cm__item .ic{width:16px; height:16px; color:var(--text-secondary);}
.dd-cm__item:hover:not(:disabled),.dd-cm__item:focus-visible{background:var(--accent-soft);} .dd-cm__item:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* [REMOVAL-185] outline:none dropped from the rule before: once the default ring yields, it left the faint tint as the only indicator */
.dd-cm__item:hover:not(:disabled) .ic,.dd-cm__item:focus-visible .ic{color:var(--accent);}
.dd-cm__item:disabled{color:var(--text-disabled); cursor:not-allowed;}
.dd-cm__item:disabled .ic{color:var(--text-disabled);}
.dd-cm__item.is-danger:not(:disabled),.dd-cm__item.is-danger:not(:disabled) .ic{color:var(--danger-ink);} /* a destructive action takes the danger colour, never a severity ink (G12) */
.dd-cm__lbl{flex:1;}
.dd-cm__state{font:700 10px var(--font-mono); padding:1px 6px; border-radius:4px; background:var(--surface-2); color:var(--text-muted); letter-spacing:.04em; text-transform:uppercase;}
.dd-cm__state.is-on{background:var(--accent-soft); color:var(--accent);}
.dd-cm__hint{font-size:10.5px; color:var(--text-muted);}
.dd-cm__sep{height:1px; background:var(--border-subtle); margin:var(--space-1) 2px;}

/* playback drawer: on the live map it ends left of the tool rail's column, as the legend does, because in a short
   window the rail reaches down into the drawer's band (History's map sets its own edges) */
.dd-pb{position:absolute; left:calc(var(--dd-lp-w) + 2 * var(--dd-gap)); right:calc(var(--dd-gap) + 52px); bottom:var(--dd-gap); z-index:calc(var(--z-dd-panel) + 2); overflow:hidden;}
/* [REMOVAL-274] .dd-live-view.has-detail .dd-pb (ended the playback left of the rail's column beside the details)
   replaced by the docked rule below: beside a right-hand panel the map had no room for it in a narrow window (G51) */
/* docked (G51): while a drone's details, the event queue or a control area is open, the playback takes the foot of the
   right-hand column at its width, in the compact layout below, and the panel ends a gap above its measured height
   (--dd-pb-h, published by DD.toastsAbove in dd-core.js); with the column empty it stays at the map's foot. The panel
   comes first in the page, so the keyboard reaches the panel, then the playback, as they are seen. */
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb{left:auto; right:var(--dd-gap); width:var(--dd-detail-w);}
.dd-live-view.has-pb :is(.dd-detail,.dd-evq,.dd-ca){bottom:calc(var(--dd-pb-h, 0px) + 2 * var(--dd-gap));}
/* at the map's foot the playback shares the legend's columns: the legend ends a gap above it and scrolls */
.dd-live-view.has-pb:not(.has-detail,.has-evq,.has-ca) .dd-legend{max-height:min(100% - 2 * var(--dd-gap) - 150px, 100% - 3 * var(--dd-gap) - 66px - var(--dd-pb-h, 0px));}
.dd-live-view.has-pb .dd-statusbar{display:none;}
/* live map: the toasts keep to its free width, from the left panel to the tool rail's column, whatever the right-hand
   column holds; where that leaves them under 300px they end at the rail's column and reach left over the panels, never
   into the rail's column or past the window's edge (an open playback lifts them: section 5) */
body.dd-page-live .dd-toasts{left:max(var(--dd-gap), min(var(--dd-rail-w) + var(--dd-lp-w) + 3 * var(--dd-gap), 100% - var(--dd-gap) - 52px - 300px)); right:calc(var(--dd-gap) + 52px); width:auto; max-width:360px; bottom:24px;}
body.dd-page-live:has(.dd-live-view:is(.has-detail,.has-evq,.has-ca)) .dd-toasts{left:max(var(--dd-gap), min(var(--dd-rail-w) + var(--dd-lp-w) + 3 * var(--dd-gap), 100% - var(--dd-detail-w) - 2 * var(--dd-gap) - 52px - 300px)); right:calc(var(--dd-detail-w) + 2 * var(--dd-gap) + 52px);}
/* [REMOVAL-264] body.dd-page-live.dd-has-pb .dd-toasts{bottom:170px;} dropped: a fixed lift cleared neither a taller playback nor the tool rail in a narrow window; the playback's measured top edge lifts the toasts on every page (section 5, G50) */
.dd-pb__hd{display:flex; align-items:center; gap:10px; height:40px; padding:0 6px 0 14px; border-bottom:1px solid var(--border-subtle); background:var(--surface-1); font-size:12.5px;}
.dd-pb__hd > .ic{color:var(--accent);}
.dd-pb__id{display:inline-flex; align-items:center; gap:6px; color:var(--text-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dd-pb__legend{margin-left:auto; display:inline-flex; align-items:center; gap:6px; color:var(--text-muted); font-size:11.5px;}
/* a narrow panel (History's map column on a smaller screen) drops the legend, which would push the Close button out of the panel */
.dd-pb{container-type:inline-size;}
@container (max-width:400px){.dd-pb__legend{display:none;}}
.dd-lg-trail,.dd-lg-pilot{display:inline-block; width:20px; height:0; border-top:2.5px solid var(--sev-high-ink); margin-left:var(--space-2);}
.dd-lg-pilot{border-top:2.5px dotted var(--text-secondary);}
.dd-pb__bd{display:flex; align-items:center; gap:var(--space-3); padding:10px 14px var(--space-3); flex-wrap:wrap;}
.dd-pb__msg{color:var(--text-muted); font-size:13px; gap:10px;}
.dd-pb__play{width:40px; height:40px; border-radius:var(--radius-round);}
.dd-pb__play .ic{width:18px; height:18px;}
.dd-pb__track{flex:1; min-width:min(200px, 100%);}
.dd-pb__slider{width:100%; accent-color:var(--accent); height:18px;}
.dd-pb__ticks{display:flex; justify-content:space-between; font:10.5px var(--font-mono); color:var(--text-muted); margin-top:-2px;}
.dd-pb__clock{display:flex; flex-direction:column; align-items:flex-end; min-width:92px;}
.dd-pb__t{font-size:15px;} .dd-pb__el{font-size:11px; color:var(--text-muted);}
.dd-pb__spd{display:flex; align-items:center; gap:6px; font-size:11px; color:var(--text-muted); font-weight:700;}
.dd-pb__spd .form-select{height:30px; width:auto; padding:0 6px; font-size:12px;}
.dd-pb__kv{display:flex; gap:14px; font-size:11.5px; color:var(--text-muted); width:100%;}
.dd-pb__kv b{font-family:var(--font-mono); color:var(--text-primary); font-weight:600;}
/* compact, docked under a right-hand panel: one row of controls with the clock, the timeline as a thin bar beneath it;
   the title, the speed label, the elapsed and total time and the timeline's ends leave the view but stay in the page
   for screen readers */
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__hd{height:34px; gap:var(--space-2); padding:0 var(--space-1) 0 10px;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) :is(.dd-pb__hd > b,.dd-pb__spd > span,.dd-pb__el,.dd-pb__ticks){position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__bd{gap:6px var(--space-2); padding:var(--space-2) 10px 10px;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) :is(.dd-pb__play,.dd-pb__rw){width:32px; height:32px;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__clock{min-width:0; margin-left:auto;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__track{order:5; flex:1 0 100%; min-width:0;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__slider{height:14px;}
.dd-live-view:is(.has-detail,.has-evq,.has-ca) .dd-pb__kv{order:6; gap:var(--space-1) 10px; flex-wrap:wrap; font-size:11px;}
.dd-pilot-route{fill:none; stroke:var(--text-secondary); stroke-width:2.2; stroke-dasharray:1 5; stroke-linecap:round;}
.dd-pb-full{opacity:.32;}
.dd-pb-done{opacity:1;}
.dd-map path.dd-pb-done.trail{stroke-width:3;}
.dd-pb-start{stroke:var(--text-primary); stroke-width:2; fill:var(--surface-0); fill-opacity:1;}
.dd-pb-end{stroke:var(--surface-0); stroke-width:2; fill:var(--text-primary); fill-opacity:1;}

/* --------------------------------------------------- 5 toasts, busy, modal */
.dd-toasts{position:fixed; right:16px; bottom:16px; z-index:var(--z-toast); display:flex; flex-direction:column; gap:var(--space-2); width:360px; max-width:calc(100vw - 32px); pointer-events:none;}
/* an open playback lifts the stack a gap above its top edge wherever the two share columns: DD.toastsAbove (dd-core.js)
   measures the panel and sets --dd-pb-top on body, and hides the oldest toasts that find no room below the top bar */
body.dd-has-pb .dd-toasts{bottom:calc(var(--dd-pb-top, 0px) + var(--dd-gap));}
.dd-toast{pointer-events:auto; display:flex; align-items:flex-start; gap:10px; padding:11px 10px 11px var(--space-4); background:var(--surface-0); border:1px solid var(--border-default); border-radius:var(--radius-md);
  box-shadow:var(--elev-4); font-size:13px; animation:dd-in var(--dur-base) var(--ease);}
.dd-toast[data-sev="info"]{--c:var(--accent);}
.dd-toast > .shp,.dd-toast__ic{margin-top:3px; width:13px; height:13px;}
.dd-toast__ic{color:var(--accent);}
.dd-toast[data-kind="ok"]{--c:var(--status-ok-fg);} .dd-toast[data-kind="ok"] .dd-toast__ic{color:var(--status-ok-fg);} /* [REMOVAL-242] .dd-toast[data-sev="low"] .dd-toast__ic replaced: a success is a status (data-kind="ok"), not a low severity (G12) */
.dd-toast__bd{flex:1; min-width:0; overflow-wrap:anywhere; display:flex; flex-direction:column; gap:1px; color:var(--text-secondary);} /* a long word wraps: a narrow toast keeps its buttons inside */
.dd-toast__bd b{color:var(--text-primary);}
.dd-supdet{margin-top:6px; font-size:12px; color:var(--text-muted);}
.dd-supdet summary{cursor:pointer; width:max-content; border-radius:4px;}
.dd-supdet summary:focus-visible{outline:none; box-shadow:var(--focus-ring);}
.dd-supdet .dd-kv{margin:6px 0 0; display:grid; grid-template-columns:max-content 1fr; gap:2px var(--space-3);}
.dd-supdet dd{margin:0; color:var(--text-primary);}
.dd-toast__x{border:0; background:none; color:var(--text-muted); border-radius:var(--radius-sm); width:26px; height:26px; display:flex; align-items:center; justify-content:center; flex:0 0 26px;}
.dd-toast__x:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-toast__act{align-self:center;}
.dd-toast.is-out{opacity:0; transform:translateY(6px); transition:all var(--dur-base);}
@media (prefers-reduced-motion: reduce){ .dd-toast{animation:none;} .dd-toast.is-out{transition:none;} }
/* system / validation messages: status colours + alert icon, never a severity shape */
.dd-toast[data-kind="warn"]{--c:var(--status-warn-fg);} .dd-toast[data-kind="warn"] .dd-toast__ic{color:var(--status-warn-fg);}
.dd-toast[data-kind="error"]{--c:var(--status-error-fg);} .dd-toast[data-kind="error"] .dd-toast__ic{color:var(--status-error-fg);}
.dd-loaderr{display:flex; align-items:flex-start; gap:10px; margin:10px 0; padding:10px var(--space-3); border-radius:var(--radius-md);
  background:var(--status-error-bg); border:1px solid var(--status-error-bd); color:var(--text-primary); font-size:13px; text-align:left;}
.dd-loaderr__ic{width:16px; height:16px; margin-top:2px; flex:0 0 16px; color:var(--status-error-fg);}
.dd-loaderr__bd{flex:1; display:flex; flex-direction:column; gap:2px;} .dd-loaderr__bd span{color:var(--text-secondary);}
.dd-loaderr .btn{align-self:center;}
.dd-loaderr-row > td{padding:0 var(--space-2);} .card > .card__bd:focus-visible,.dd-zones__side > .dd-zlist:focus-visible{outline-offset:-2px;} /* boxes DD.loadError holds the focus on: their card or column clips an outer ring */
/* live picture paused / no sensor data: banner over the map, markers dimmed (positions are not current) */
.dd-livewarn{position:absolute; top:12px; left:50%; transform:translateX(-50%); z-index:var(--z-sidebar); max-width:min(640px,calc(100% - 32px));
  display:flex; align-items:flex-start; gap:10px; padding:10px 14px; border-radius:var(--radius-md); box-shadow:var(--elev-2);
  background:var(--status-error-bg); border:1px solid var(--status-error-bd); color:var(--status-error-fg); font-size:13px;}
.dd-livewarn .ic{width:16px; height:16px; margin-top:2px; flex:0 0 16px;}
.dd-livewarn b{color:var(--text-primary);} .dd-livewarn span{color:var(--text-secondary);}
.dd-livewarn__bd{display:flex; flex-direction:column; gap:2px;}
.dd-live-view.is-stale .leaflet-marker-pane,.dd-live-view.is-stale .leaflet-overlay-pane{opacity:.45; filter:grayscale(.6);}
.dd-tilewarn{background:var(--surface-0); border:1px solid var(--status-warn-bd); color:var(--text-secondary); border-radius:var(--radius-md); padding:6px 10px; font-size:12px; max-width:280px;}
@keyframes dd-in{from{opacity:0; transform:translateY(8px);} to{opacity:1; transform:none;}}
.dd-busy{position:fixed; top:calc(var(--dd-top-h) + 12px); left:50%; transform:translateX(-50%); z-index:var(--z-dd-busy); display:flex; align-items:center; gap:10px;
  padding:var(--space-2) var(--space-4); border-radius:var(--radius-pill); background:var(--surface-0); border:1px solid var(--border-default); box-shadow:var(--elev-3); font-size:12.5px; font-weight:600; color:var(--text-secondary);}
.dd-modal-scrim{z-index:var(--z-dd-scrim);}
.dd-modal .modal__bd{max-height:70vh;}
.dd-modal .modal__sub{font-size:12.5px;}
.dd-modal .field{margin-bottom:var(--space-3);}
/* [REMOVAL-241] .dd-modal[data-sev] .modal__hd::before dropped: airspace-ops.css draws the one severity header bar of modals and windows (G19) */
.dd-confirm{margin:0; color:var(--text-secondary);}
.dd-mhead{display:flex; align-items:center; gap:10px; padding:9px var(--space-3) 9px var(--space-4); background:var(--surface-1); border:1px solid var(--border-subtle); border-radius:var(--radius-md); margin-bottom:14px;}
.dd-mhead > div{flex:1; display:flex; flex-direction:column; font-size:13px;}
.dd-mhead .dd-mono{font-size:11.5px; color:var(--text-secondary);}
.dd-mhead .shp{width:14px; height:14px;}
.dd-sect-cap{font-size:10px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-muted); margin:6px 0 var(--space-2);}
.dd-contacts{display:flex; flex-direction:column; gap:6px; margin-bottom:14px; max-height:260px; overflow:auto;}
.dd-contact{display:flex; align-items:center; gap:10px; padding:9px var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1); cursor:pointer;}
.dd-contact:has(input:checked){border-color:var(--accent); background:var(--accent-soft);}
.dd-contact input{accent-color:var(--accent); width:16px; height:16px;}
.dd-contact__bd{flex:1; min-width:0; display:flex; flex-direction:column; font-size:12.5px;}
.dd-contact__bd span{color:var(--text-muted); font-size:11.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dd-loading{display:flex; gap:var(--space-2); align-items:center; color:var(--text-muted); font-size:12.5px; padding:var(--space-2) 0;}
.dd-empty-sm.empty-state{padding:14px;}
.dd-linkbox{display:flex; gap:var(--space-2); align-items:center;}
.dd-linkbox .form-control{flex:1; font-size:12px;}
.dd-share__warn{margin:var(--space-3) 0 0;}
.dd-qrbox{display:flex; gap:var(--space-4); align-items:center; margin-top:var(--space-3); padding:var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-qr{flex:none; line-height:0; border-radius:var(--radius-sm); overflow:hidden; border:1px solid var(--border-subtle);}
.dd-qr svg{width:var(--dd-qr-size); height:var(--dd-qr-size); display:block;}
.dd-qr__bg{fill:var(--dd-qr-bg);}
.dd-qr__fg{fill:var(--dd-qr-fg);}
.dd-qrbox__bd{flex:1; min-width:0; display:flex; flex-direction:column; gap:var(--space-2); font-size:13px;}
.dd-qrbox__act{display:flex; flex-wrap:wrap; gap:var(--space-2);}
@media (max-width:520px){.dd-qrbox{flex-direction:column; align-items:stretch;} .dd-qr{align-self:center;}}
.dd-toggles{display:flex; flex-direction:column; gap:var(--space-2); margin-bottom:14px;}
.dd-toggle{display:flex; align-items:center; gap:var(--space-3); padding:var(--space-2) var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1); cursor:pointer;}
.dd-toggle__bd{display:flex; flex-direction:column; font-size:13px;}
.dd-toggle__bd span{font-size:11.5px; color:var(--text-muted);}
.switch input:focus-visible + .track{box-shadow:var(--focus-ring);}
.switch input:disabled + .track{opacity:.5; cursor:not-allowed;}
.dd-toggle:has(input:disabled){cursor:not-allowed;}
.dd-inline-form{display:flex; align-items:flex-end; gap:10px; flex-wrap:wrap; margin-bottom:var(--space-3);}
.dd-inline-form .field{margin-bottom:0;}
.dd-oh-table{max-height:340px;}

/* ------------------------------------------------------------ 6 pages */
.dd-page{max-width:1320px; padding:var(--space-5) 28px 40px;}
.dd-page--wide{max-width:1600px;}
.dd-page .page__head{margin-bottom:18px;}
.page__title .dd-title-ic,.dd-title-ic{width:22px; height:22px; color:var(--accent); margin-right:var(--space-1); vertical-align:-3px;}
.dd-page-head{display:flex; align-items:flex-end; justify-content:space-between; gap:var(--space-4); margin-bottom:14px;}
.dd-page-actions{display:flex; gap:var(--space-2); flex-wrap:wrap;}
.card__hd h3{display:flex; align-items:center; gap:var(--space-2); font-size:.95rem;}
.card__hd h3 .ic{color:var(--accent);}
/* a scroll box with sticky parts (a list header, the Events bulk-action bar, the mobile page's header; the root for
   the window): keyboard focus and scrollIntoView stop clear of them, by how far they reach in, measured by dd-core.js */
.dd-sticky-pad{scroll-padding-top:var(--dd-sticky-top, 0px); scroll-padding-bottom:var(--dd-sticky-bottom, 0px);}
/* an element taller than that room, taking the keyboard focus: its scroll box, ring included, is the room's height,
   so every alignment shows its top at the sticky top edge (a negative bottom margin, set by dd-core.js; it outranks
   the focus rules' scroll margins, and a click, which shows no ring, keeps the row under the pointer) */
.dd-sticky-pad .dd-sticky-tall:focus-visible{scroll-margin-top:var(--dd-tall-top, 0px); scroll-margin-bottom:var(--dd-tall-bottom, 0px);}
.table-wrap{background:var(--surface-0);} .table-wrap:has(> table:focus-visible){outline:2px solid var(--accent); outline-offset:1px;} /* a table holds the focus only for DD.loadError; the wrap clips the table's own ring */
.data td .shp{margin-right:var(--space-1);}
.data tbody tr.sev-bar{box-shadow:inset 3px 0 0 var(--c);}
.dd-row-off td{opacity:.55;} .dd-l-removed{margin-top:3px; font-size:11.5px; color:var(--text-secondary);}
.data .dd-num,.dd-num{text-align:right;} /* [REMOVAL-237] !important dropped: .data .dd-num outranks the platform's .data thead th (G22) */
.data td.dd-mono,.dd-nowrap{white-space:nowrap;}
.dd-rowact{text-align:right; white-space:nowrap;}
.dd-rowact .btn + .btn{margin-left:var(--space-1);}
.dd-cell-remark{max-width:360px; color:var(--text-secondary);}
.dd-rowlink{cursor:pointer;}
.dd-rowlink:focus-visible{outline:2px solid var(--accent); outline-offset:-2px; scroll-margin:0;} /* the ring is inset, so the default ring's scroll margin only made the box the focus scrolls into view taller: a row nearly as tall as the room under the sticky header then outgrew it, and the browser aligned its bottom, leaving its top under the header */
.dd-cell-drone{display:inline-flex; align-items:center; gap:9px; white-space:nowrap;}
.dd-cell-drone .dd-mini{width:22px; height:22px; flex-basis:22px; border-radius:7px;} .dd-cell-drone .dd-mini svg{width:13px; height:13px;}
.dd-viols{display:flex; flex-wrap:wrap; gap:var(--space-1); max-width:320px;}
.dd-vchip{display:inline-flex; align-items:center; gap:var(--space-1); font-size:11px; padding:1px 7px; border-radius:5px; background:var(--surface-2); color:var(--text-secondary); white-space:nowrap;}
.dd-vchip .shp{margin:0;} /* [REMOVAL-213] width/height 8px dropped: a violation chip names its rule, not its severity, so the shape takes the 12 px floor (G02) */
.dd-filterbar{display:flex; align-items:flex-end; gap:10px; flex-wrap:wrap; padding:var(--space-3) 14px; margin-bottom:var(--space-3); overflow:visible;}
/* --dd-ph-w: what a search field needs to show its whole placeholder in the page's language (measured in dd-core.js),
   so the bar wraps the field onto the next line rather than cut the text */
.dd-filterbar .field{margin:0; min-width:max(130px, var(--dd-ph-w, 0px));}
.dd-filterbar .dd-f-grow{flex:1; min-width:max(180px, var(--dd-ph-w, 0px));}
.dd-filterbar .segmented{align-self:flex-end; margin-bottom:1px;}
.segmented button.on{color:var(--text-primary);}
.dd-tablebar{display:flex; align-items:center; gap:10px; min-height:22px; margin:2px 2px var(--space-2); font-size:12.5px;}
.dd-toolbar-search{min-width:300px;}
.dd-grid-main{display:grid; grid-template-columns:minmax(0,1fr) 380px; gap:var(--space-4); align-items:start;}
.dd-col{display:flex; flex-direction:column; gap:var(--space-4); min-width:0;}
.dd-flat{border:0; border-radius:0;} .dd-flat:has(> table:focus-visible){outline-offset:-2px;} /* inset: the card around a flat wrap clips it */
.dd-sevcell{display:inline-flex; align-items:center; gap:5px; font-size:12.5px; white-space:nowrap;}
.dd-sevcell b{font-family:var(--font-mono);}
/* [REMOVAL-001] inline-flex + justify-content:flex-end dropped: the right-aligned, content-sized group let optional trailing buttons push the primary action left */
.dd-evacts{display:flex; gap:2px; flex-wrap:wrap;} /* wraps rather than widen the table past the page (G08) */
.dd-e-owner{display:flex; align-items:center; gap:var(--space-1); margin-top:var(--space-1); white-space:nowrap;} .dd-e-owner .ic{width:13px; height:13px;}
.dd-evacts .btn-sm{padding:.3rem .45rem;}
.dd-evacts .btn span{display:none;}
.dd-evacts .btn-primary span{display:inline;}
.dd-evacts__slot{visibility:hidden;}
.dd-notes-row td{background:var(--surface-1);}
.dd-notes{list-style:none; margin:0; padding:var(--space-1) 0 var(--space-1) 18px; display:flex; flex-direction:column; gap:6px;}
.dd-notes li{display:flex; gap:var(--space-3); font-size:12.5px;}
/* [REMOVAL-240] .dd-error dropped: no page uses it since the error pages became the standalone .dd-err page (REMOVAL-016, G29) */

/* history split */
.dd-stage--split{overflow:hidden;}
.dd-split{display:grid; grid-template-columns:minmax(0,1.75fr) minmax(360px,1fr); height:100%;}
/* the flights table fits beside the map at 1440 x 900 with the rail pinned open (G08, DS-T12): two-line cells for
   time and duration, drone and serial; violation chips stack and wrap; headers wrap; 10 px cell padding.
   [REMOVAL-221] .dd-h-table .dd-viols{flex-wrap:nowrap} dropped: the chips stack and wrap instead of widening the table */
.dd-h-table .data td{white-space:nowrap;}
.dd-h-table .data td.dd-h-viols{white-space:normal;}
.dd-h-table .dd-viols{flex-direction:column; align-items:flex-start;}
.dd-h-table .dd-vchip{white-space:normal; max-width:160px;}
.dd-h-table .data thead th{white-space:normal;}
/* a distance of 1,000 km or more ("1.383,9 km") takes no more room than "999,9 km" and ends in an ellipsis, the whole
   value in its tooltip and its text, so one long flight never widens the table past its box */
.dd-h-dist{display:inline-block; max-width:8ch; overflow:hidden; text-overflow:ellipsis; vertical-align:top;}
/* a table that shares the page with a map or a side list keeps 8 px of side padding, so it fits at 1440 px with the
   rail pinned open (G08) */
.data.dd-data-tight thead th,.data.dd-data-tight tbody td{padding-left:var(--space-2); padding-right:var(--space-2);}
.dd-cell-drone__bd{display:flex; flex-direction:column; min-width:0;}
.dd-th-sub{display:block; font-weight:600; text-transform:none; letter-spacing:0;}
.tl--compact i{width:12px; height:12px; flex-basis:12px;} /* lamps without their name (hover card, flights table): 12 px shapes (G02) */
.dd-split .dd-filterbar{gap:var(--space-2) 10px; padding:10px var(--space-3);}
.dd-split .dd-filterbar .form-control,.dd-split .dd-filterbar .form-select{height:32px; font-size:12.5px;}
.dd-split .dd-filterbar .field{min-width:104px;}
.dd-split .dd-filterbar input[type=datetime-local]{width:196px;}
.dd-split__main{display:flex; flex-direction:column; min-height:0; padding:20px 20px var(--space-4) var(--space-5); overflow:hidden;}
.dd-split__side{position:relative; border-left:1px solid var(--border-subtle);}
/* [REMOVAL-302] scroll-padding-top:var(--dd-h-head) dropped: the list's padding is .dd-sticky-pad's (section 6), measured by DD.stickyParts in dd-core.js for every scroll box with a sticky part */
.dd-h-table{flex:1; min-height:0;}
.dd-hist-map .dd-pb{left:12px; right:12px; bottom:12px;}
/* [REMOVAL-265] Moved to section 5 as body.dd-has-pb .dd-toasts: one lift above an open playback for History and the live map, measured by DD.toastsAbove in dd-core.js instead of history.js (G50) */
.dd-hist-map .leaflet-bottom.leaflet-right{bottom:0;}
.dd-h-hint{position:absolute; left:50%; top:16px; transform:translateX(-50%); z-index:var(--z-dd-panel); display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) 14px; font-size:12.5px; color:var(--text-secondary);}
.dd-h-hint .ic{color:var(--accent);}
.dd-hist-map:has(.dd-bm-panel:not([hidden])) .dd-h-hint{visibility:hidden;}
.dd-split .dd-filterbar .field{min-width:max(120px, var(--dd-ph-w, 0px));}

/* objects & zones */
.dd-mapsplit{display:grid; grid-template-columns:minmax(0,1fr) 440px; height:100%;}
.dd-mapsplit__map{position:relative;}
.dd-mapsplit__side{border-left:1px solid var(--border-subtle); background:var(--surface-0); overflow:auto; padding:18px 18px var(--space-5);}
.dd-side-head{display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-3); margin-bottom:14px;}
.dd-side-head .page__title{font-size:1.25rem;}
.dd-side-search{margin-bottom:var(--space-3);}
.dd-olist{display:flex; flex-direction:column; gap:var(--space-2);}
.dd-ocard{border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1); overflow:hidden;}
.dd-ocard.is-sel{border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset;}
.dd-ocard__main{display:flex; align-items:center; gap:10px; width:100%; padding:10px var(--space-3) 6px; border:0; background:none; color:inherit; text-align:left;} .dd-ocard__main:focus-visible{outline-offset:-2px;} /* inset: the card clips an outer ring */
.dd-ocard__ic{width:32px; height:32px; border-radius:var(--radius-md); background:var(--zone-protected-fill); color:var(--zone-protected-stroke); border:1px solid color-mix(in srgb,var(--zone-protected-stroke) 45%,transparent); display:flex; align-items:center; justify-content:center; flex:0 0 32px;}
.dd-ocard__bd{flex:1; min-width:0; display:flex; flex-direction:column;}
.dd-ocard__bd b{font-size:13.5px;} .dd-ocard__bd span{font-size:11.5px; color:var(--text-muted);}
.dd-ocard__meta{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-3); padding:0 var(--space-3) 6px 54px; font-size:11.5px; color:var(--text-secondary);}
.dd-ocard__meta span{display:inline-flex; align-items:center; gap:var(--space-1);}
.dd-ocard__meta .ic{width:12px; height:12px; color:var(--text-muted);}
.dd-ocard__acts{display:flex; gap:2px; padding:var(--space-1) var(--space-2) 6px 46px; border-top:1px solid var(--border-subtle);}
.dd-oform__hd{display:flex; align-items:center; justify-content:space-between; margin-bottom:10px;}
.dd-oform__hd h2{font-size:1.05rem; margin:0;}
.dd-oform__ft{display:flex; gap:var(--space-2); align-items:center; margin-top:14px; padding-top:14px; border-top:1px solid var(--border-subtle);}
.dd-toggles--grid .dd-toggle{padding:6px 10px;}
.dd-polystate{margin-bottom:10px;}
.dd-polystate .form-help{margin:6px 0 0;}
.dd-drawhint{position:absolute; top:12px; left:50%; transform:translateX(-50%); z-index:var(--z-map-chrome); display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) 14px; font-size:12.5px; color:var(--text-primary); border-color:var(--accent);}
.dd-drawhint .ic{color:var(--accent);}
.dd-editpoly{stroke:var(--accent); stroke-width:2.2; stroke-dasharray:6 4; fill:var(--accent); fill-opacity:.1;}
.leaflet-editing-icon,.dd-vertex{background:var(--surface-0); border:2px solid var(--accent); border-radius:3px;} /* [REMOVAL-238] !important dropped: console.css loads after leaflet.css, so this rule outranks .leaflet-div-icon at the same weight (G22) */
.dd-zones{display:grid; grid-template-columns:minmax(0,1fr) 380px; gap:var(--space-4); height:calc(100vh - 250px); min-height:460px;}
.dd-zones__map{position:relative; overflow:hidden;}
.dd-zones__side{overflow:auto; padding:var(--space-1); margin:-4px;} /* the padding keeps a control's focus ring inside the scroll box, the margin keeps the layout */
.dd-zlist{display:flex; flex-direction:column; gap:6px;}
.dd-zrow{display:flex; align-items:center; gap:10px; padding:6px var(--space-2) 6px var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-0);}
.dd-zrow__main{flex:1; min-width:0; display:flex; flex-direction:column; border:0; background:none; text-align:left; color:inherit; padding:2px 0;}
.dd-zrow__main span{font-size:11.5px; color:var(--text-muted);}
/* the event a zone raises (R1-23): severity shape, ink and label; "No events" for an allow zone stays muted */
.dd-zrow__main .dd-zrow__ev{display:inline-flex; align-items:center; gap:var(--space-1); font-weight:700;}
.dd-zrow__main .dd-zrow__ev.sev-ink span{color:inherit;}
.dd-zform .card__bd .field{margin-bottom:10px;}
.dd-level{display:inline-flex; align-items:center; gap:3px;}
.dd-level i{width:14px; height:8px; border-radius:2px; background:var(--surface-2); border:1px solid var(--border-default);}
.dd-level i.on{background:var(--text-secondary); border-color:var(--text-secondary);}
.dd-level b{margin-left:6px;}
.dd-rolepick{display:grid; grid-template-columns:1fr; gap:6px; margin-bottom:var(--space-3);} .dd-rolepick .dd-contact__bd span{white-space:normal;}
/* areas of responsibility (admin): checklists of sensors, connections, users and areas; a linked station is
   outlined in the area colour; the users' access column */
.dd-accesspick{display:grid; grid-template-columns:1fr; gap:6px; margin-bottom:var(--space-2);} .dd-accesspick .dd-contact__bd span{white-space:normal;}
.dd-accesspick .dd-contact:has(input:disabled){cursor:default; opacity:.7;}
#dd-u-admin-note{margin:0 0 var(--space-3);}
.dd-ar-intro{max-width:880px; margin:0 0 var(--space-3);}
.dd-arset{border:0; margin:0 0 var(--space-3); padding:0; min-width:0;}
.dd-arset > legend{padding:0;}
.dd-arset > .form-help{margin:0 0 6px;}
.dd-checklist{display:flex; flex-direction:column; gap:var(--space-1); max-height:220px; overflow:auto; padding:2px;}
.dd-checkrow{display:flex; align-items:flex-start; gap:10px; margin:0; padding:7px 10px; border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  background:var(--surface-1); cursor:pointer; font-size:12.5px; color:var(--text-primary);}
.dd-checkrow:has(input:checked){border-color:var(--aor-edge);}
.dd-checkrow:has(input:focus-visible){box-shadow:var(--focus-ring);}
.dd-checkrow input{accent-color:var(--accent); width:16px; height:16px; margin:1px 0 0; flex:0 0 16px;}
.dd-checkrow__bd{flex:1; min-width:0; display:flex; flex-direction:column; overflow-wrap:anywhere;}
.dd-ar-share[data-share="none"]{font-style:italic;}
#dd-ar-share{margin-bottom:10px;} #dd-ar-share:empty{display:none;}
.dd-station[data-linked="true"]{outline:2px dashed var(--aor-edge); outline-offset:1px;}
.dd-station__aor{color:var(--aor-edge);}
.dd-aor-station{outline:none;}
.dd-aor-station:focus-visible .dd-station{box-shadow:var(--focus-ring);}
.leaflet-interactive.dd-aor-station .dd-station{cursor:pointer;}
.leaflet-tooltip.dd-maptip{background:var(--surface-0); color:var(--text-primary); border:1px solid var(--border-default); box-shadow:var(--elev-1); border-radius:4px; font-size:12px;}
.leaflet-tooltip.dd-maptip::before{display:none;}
.dd-access{display:inline-flex; align-items:center; gap:6px; max-width:280px;}
.dd-access .ic{width:14px; height:14px; flex:0 0 14px; color:var(--aor-edge);}
.dd-access > span{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.dd-rs-grid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--space-1) 18px;}
.dd-unit{display:flex; align-items:center; gap:var(--space-2);}
.dd-unit .form-control{max-width:160px;}
.dd-unit span{font-family:var(--font-mono); font-size:12px; color:var(--text-muted);}
.dd-pred__t{font-size:15px; font-weight:700; margin:0 0 6px;}
.dd-pred .status-pill[data-status="warn"]{background:var(--surface-2); border-color:var(--border-default); color:var(--text-secondary);}
.dd-tabpane{min-height:300px;}

/* dispatch page */
.dd-livepick{display:flex; flex-direction:column; gap:6px; max-height:360px; overflow:auto;}
.dd-lp-item{display:flex; align-items:center; gap:10px; padding:var(--space-2) 10px var(--space-2) 14px; border-radius:var(--radius-md); background:var(--surface-1); border:1px solid var(--border-subtle);}
.dd-lp-item__bd{flex:1; min-width:0; display:flex; flex-direction:column; font-size:13px;}
.dd-lp-item__bd .dd-mono{font-size:11.5px; color:var(--text-secondary);}
.dd-ctlist{display:flex; flex-direction:column;}
.dd-ct{display:flex; align-items:flex-start; gap:10px; padding:var(--space-3) var(--space-4); border-bottom:1px solid var(--border-subtle);}
.dd-ct:last-child{border-bottom:0;}
.dd-ct__bd{flex:1; min-width:0; display:flex; flex-direction:column; font-size:13px;}
.dd-ct__bd > span{font-size:12px; color:var(--text-secondary);}
.dd-ct__tags{display:flex; gap:5px; margin-top:5px;}

/* reports */
.dd-r-kpis{margin-bottom:var(--space-4);}
.dd-kpi-sev .kpi__label{display:flex; align-items:center; gap:6px;}
.dd-kpi-sev .kpi__value{color:var(--text-primary);}
.dd-r-grid{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--space-4); align-items:start;}
.dd-bars{width:100%; border-collapse:collapse; font-size:12.5px;}
.dd-bars th{text-align:left; font-weight:600; color:var(--text-secondary); padding:5px 10px 5px 0; white-space:nowrap; width:1%;}
.dd-bars th .shp{margin-right:6px;}
.dd-bars__bar{width:100%; padding:5px 0;}
.dd-bar{display:block; height:12px; border-radius:0 4px 4px 0; background:var(--accent);}
.dd-bar--sev[data-sev="low"]{background:var(--sev-low);} .dd-bar--sev[data-sev="medium"]{background:var(--sev-medium);} .dd-bar--sev[data-sev="high"]{background:var(--sev-high);} .dd-bar--sev[data-sev="critical"]{background:var(--sev-critical);}
.dd-bars__n{text-align:right; padding-left:10px; white-space:nowrap; color:var(--text-primary);}
.dd-bars tr:hover th{color:var(--text-primary);}

/* ------------------------------------------------------------ 7 login */
.dd-login{min-height:100vh; display:flex; align-items:center; justify-content:center; padding:var(--space-6) var(--space-4); position:relative; overflow:hidden;
  background:radial-gradient(120% 90% at 50% 0%,var(--sidebar-bg-top) 0%,var(--sidebar-bg-mid) 45%,var(--canvas) 100%);}
:root[data-theme="light"] .dd-login{background:radial-gradient(120% 90% at 50% 0%,var(--dd-login-glow) 0%,var(--canvas) 70%);}
.dd-login__bg{position:absolute; inset:0; color:rgba(var(--dd-chrome-accent-rgb),.08); pointer-events:none;}
.dd-login__bg svg{width:100%; height:100%;}
.dd-login__col{position:relative; width:100%; max-width:440px; display:flex; flex-direction:column; gap:var(--space-4);}
.dd-login__brand{display:flex; justify-content:center; margin-bottom:var(--space-2);}
.dd-login__brand img{width:320px; max-width:90%;}
.dd-login__card .card__bd{padding:26px 26px 22px;}
.dd-login__title{font-size:1.2rem; margin:0;}
.dd-login__sub{color:var(--text-muted); margin:2px 0 18px; font-size:13px;}
.dd-login__form .btn-block{margin-top:6px;}
.dd-login__demo .card__bd{padding:var(--space-3) 14px;}
.dd-demo-table{font-size:12.5px;}
.dd-demo-row{cursor:pointer;}
.dd-demo-row:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;}
.dd-demo-area{display:flex; align-items:center; gap:5px; margin-top:var(--space-1); font-size:11.5px; color:var(--text-muted);}
.dd-demo-area .ic{width:13px; height:13px; flex:0 0 13px; color:var(--aor-edge);}
.dd-login__foot{display:flex; align-items:center; justify-content:center; gap:var(--space-3); color:var(--text-muted); font-size:11px;}
.dd-login__foot .dd-lang{border-color:var(--border-default);}
.dd-login__foot .dd-lang__btn{color:var(--text-secondary);}
.dd-login__foot .dd-lang__btn:hover,.dd-login__foot .dd-lang__btn[aria-expanded="true"]{color:var(--text-primary); background:var(--surface-1);}
.dd-login__foot .dd-menu{right:auto; left:0;}
/* the organisation choice after signing in (templates/login_tenant.html, R1-91b) */
.dd-tenant-pick__form{margin:0;}
.dd-tenant-pick__list{list-style:none; margin:var(--space-3) 0 0; padding:0; display:flex; flex-direction:column; gap:var(--space-2);}
.dd-tenant-pick__opt{display:flex; align-items:center; gap:var(--space-3); width:100%; padding:var(--space-3) var(--space-4); text-align:left; cursor:pointer;
  border:1px solid var(--border-default); border-radius:var(--radius-md); background:var(--surface-1); color:var(--text-primary);}
.dd-tenant-pick__opt:hover{background:var(--surface-2); border-color:var(--border-strong);}
.dd-tenant-pick__opt:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.dd-tenant-pick__opt[aria-current="true"]{border-color:var(--accent);}
.dd-tenant-pick__glyph{display:flex; align-items:center; justify-content:center; width:36px; height:36px; flex:0 0 36px;
  border-radius:var(--radius-md); background:var(--accent-soft); color:var(--accent);}
.dd-tenant-pick__glyph .ic{width:18px; height:18px;}
.dd-tenant-pick__bd{flex:1; min-width:0; display:flex; flex-direction:column; line-height:1.35;}
.dd-tenant-pick__nm{font-size:14px; overflow-wrap:anywhere;}
.dd-tenant-pick__role{font-size:12px; color:var(--text-muted);}
.dd-tenant-pick .dd-tenant-pick__go{width:16px; height:16px; flex:0 0 16px; color:var(--text-muted);}
.dd-tenant-pick__out{display:flex; justify-content:center; margin:var(--space-4) 0 0;}

/* ------------------------------------------------------------ 7b error pages (direction A; reuses the login backdrop) */
.dd-err__col{max-width:520px;}
.dd-err__card .card__bd{padding:28px 28px var(--space-5); display:flex; flex-direction:column; align-items:flex-start; gap:10px;}
.dd-err__glyph{width:44px; height:44px; border-radius:var(--radius-lg); display:flex; align-items:center; justify-content:center;
  background:var(--accent-soft); color:var(--accent); border:1px solid var(--border-default);}
.dd-err__glyph .ic{width:22px; height:22px;}
.dd-err[data-tone="warn"] .dd-err__glyph{background:var(--status-warn-bg); color:var(--status-warn-fg); border-color:var(--status-warn-bd);}
.dd-err[data-tone="error"] .dd-err__glyph{background:var(--status-error-bg); color:var(--status-error-fg); border-color:var(--status-error-bd);}
.dd-err__title{font-size:1.35rem; margin:var(--space-1) 0 0; color:var(--text-primary);}
.dd-err__lead{margin:0; color:var(--text-secondary); font-size:14.5px; line-height:1.55;}
.dd-err__acts{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-top:var(--space-2);}
.dd-err__support{display:flex; gap:var(--space-2); align-items:flex-start; margin:6px 0 0; color:var(--text-muted); font-size:13px;}
.dd-err__support .ic{width:15px; height:15px; margin-top:2px; flex:0 0 15px;}
.dd-err__details{width:100%; margin-top:6px; border-top:1px solid var(--border-subtle); padding-top:10px; font-size:12.5px; color:var(--text-muted);}
.dd-err__dethd{margin:0; font-size:12.5px; font-weight:600; color:var(--text-muted);}
.dd-err__acts .btn:focus-visible{outline:none; box-shadow:var(--focus-ring);}
.dd-err__details .dd-kv{margin:var(--space-2) 0 0; display:grid; grid-template-columns:max-content 1fr; gap:var(--space-1) 14px;}
.dd-err__details dd{margin:0; color:var(--text-primary);}
.dd-err__sweep{transform-origin:400px 400px; animation:dd-err-sweep var(--err-dur-sweep) linear infinite;}
@keyframes dd-err-sweep{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion: reduce){ .dd-err__sweep{animation:none;} }
@media (max-width:480px){
  .dd-err{align-items:flex-start; padding-top:var(--space-5);}
  .dd-err__card .card__bd{padding:22px 18px 18px;}
  .dd-err__acts{flex-direction:column; align-items:stretch; width:100%;}
  .dd-err__acts .btn{min-height:44px; justify-content:center;}
  .dd-login__brand img{width:260px;}
}

/* ------------------------------------------------------ 8 mobile dispatch */
.dd-mobile-page{background:var(--canvas);}
.dd-m{max-width:640px; margin:0 auto; min-height:100vh; display:flex; flex-direction:column;}
.dd-m__top{position:sticky; top:0; z-index:var(--z-overlay); display:flex; align-items:center; gap:10px; padding:10px var(--space-4); background:linear-gradient(90deg,var(--sidebar-bg-top),var(--sidebar-bg-mid)); color:var(--dd-chrome-fg); border-bottom:1px solid var(--dd-chrome-edge);}
.dd-m__brand{display:flex; flex-direction:column; line-height:1.2; flex:1;}
.dd-m__brand b{font-size:13px; letter-spacing:.06em;} .dd-m__brand span{font-size:11px; color:var(--dd-chrome-muted);}
.dd-m__upd{display:inline-flex; align-items:center; gap:6px; font:700 11px var(--font-mono); color:var(--dd-chrome-warn);}
.dd-m__upd .dd-live__dot{width:8px; height:8px; border-radius:var(--radius-round); border:1.5px solid currentColor;}
.dd-m__upd[data-state="live"]{color:var(--live-400);}
.dd-m__upd[data-state="live"] .dd-live__dot{background:var(--live-400); animation:ds-live-pulse var(--live-dur-pulse) ease-out infinite;}
.dd-m__upd[data-state="stale"]{color:var(--dd-chrome-error);}
.dd-m__warn{background:var(--status-error-bg); border:1px solid var(--status-error-bd); color:var(--text-primary); border-radius:var(--radius-lg); padding:10px 14px; font-size:14px;}
.dd-m__warn b{display:block; color:var(--status-error-fg);}
.dd-m main{flex:1; display:flex; flex-direction:column; gap:var(--space-3); padding:var(--space-3) var(--space-4) var(--space-5);}
.dd-m__banner{background:var(--surface-0); border:1px solid var(--border-subtle); border-radius:var(--radius-lg); padding:var(--space-3) 14px var(--space-3) 18px;}
.dd-m__loading{display:flex; gap:10px; align-items:center; color:var(--text-muted);}
.dd-m__id{display:flex; align-items:center; gap:var(--space-3);}
.dd-m__id > div{flex:1; min-width:0; display:flex; flex-direction:column;}
.dd-m__id b{font-size:17px;} .dd-m__id .dd-mono{font-size:12.5px; color:var(--text-secondary);}
.dd-m__shape{width:20px; height:20px;}
.dd-m__viol{list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:var(--space-1);}
.dd-m__viol li{display:flex; align-items:center; gap:var(--space-2); font-size:14px; font-weight:700;} /* [REMOVAL-217] color:var(--sev-critical-ink) dropped: .sev-ink gives each violation its own severity's ink (G04) */
.dd-m__closed{margin-top:var(--space-2); font-size:13px; color:var(--text-muted);}
.dd-m__mapbox{position:relative; height:44vh; min-height:260px; border-radius:var(--radius-lg); overflow:hidden; border:1px solid var(--border-subtle);}
.dd-m__recenter{position:absolute; left:10px; bottom:10px; z-index:var(--z-control); width:44px; height:44px; border-radius:var(--radius-lg); background:var(--surface-0); border:1px solid var(--border-default); color:var(--text-primary); display:flex; align-items:center; justify-content:center; box-shadow:var(--elev-2);}
.dd-m__recenter .ic{width:20px; height:20px;}
.dd-m__routes{display:flex; flex-direction:column; gap:10px;}
.dd-m__route{display:flex; align-items:center; gap:14px; width:100%; min-height:64px; padding:10px var(--space-4); border-radius:var(--radius-lg); border:1.5px solid var(--border-strong); background:var(--surface-0); color:var(--text-primary); text-align:left;}
.dd-m__route.is-on{border-color:var(--accent); background:var(--accent-soft);}
.dd-m__route:disabled{opacity:.45;}
.dd-m__route-ic{width:42px; height:42px; border-radius:var(--radius-lg); background:var(--accent); color:var(--on-accent); display:flex; align-items:center; justify-content:center; flex:0 0 42px;}
.dd-m__route-ic .ic{width:22px; height:22px;}
.dd-m__route-bd{flex:1; display:flex; flex-direction:column;}
.dd-m__route-bd b{font-size:16px;} .dd-m__route-bd span{font-size:12.5px; color:var(--text-secondary);}
.dd-m__route > .ic{color:var(--text-muted);}
.dd-m__ext{display:grid; grid-template-columns:1fr; gap:var(--space-2);}
.dd-m__ext{min-width:0;}
.dd-m__ext .btn{width:100%; min-width:0; white-space:normal; text-align:center;}
.dd-m__ext2{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--space-2);}
.dd-m__ext2 .btn{padding:.55rem .4rem; font-size:.8rem;}
.dd-m__me{align-self:center;}
.dd-m__me.is-on{color:var(--accent);}
.dd-m__card{background:var(--surface-0); border:1px solid var(--border-subtle); border-radius:var(--radius-lg); padding:var(--space-3) 14px;}
.dd-m__card h2{font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--text-muted); margin:0 0 var(--space-2);}
.dd-m__card p{margin:0; font-size:14px;}
.dd-m__card .dd-kv{font-size:14px;}
.dd-m__foot{font-size:11.5px; color:var(--text-muted); text-align:center; padding-top:var(--space-1);}
.dd-m__expired{margin-top:40px;}
.dd-m-route{fill:none; stroke:var(--accent); stroke-width:4; stroke-linecap:round; stroke-dasharray:1 8;}
.dd-m-origin{stroke:var(--surface-0); stroke-width:3; fill:var(--accent); fill-opacity:1;}

/* ------------------------------------------------------------ 9 light theme */
/* [REMOVAL-104] :root[data-theme="light"] .dd-evbar dropped from this rule: the card strip is gone; .dd-evsum takes its place */
:root[data-theme="light"] .dd-live-view .map-panel,:root[data-theme="light"] .dd-evsum{background:color-mix(in srgb,var(--surface-0) 96%,transparent);}
:root[data-theme="light"] .dd-trk__hdg i{filter:none;}
:root[data-theme="light"] .dd-rail-badge{box-shadow:0 0 0 2px var(--dd-chrome-mid);}

/* ------------------------------------------------------------ 10 responsive */
@media (max-width:1380px){
  :root[data-palette="airspace"]{--dd-lp-w:304px; --dd-detail-w:360px;}
  .dd-user__nm{display:none;}
  .dd-chip-sensors__lbl{display:none;}
}
@media (max-width:1280px){
  .dd-ctx{display:none;}
  .dd-area-pill{max-width:200px;}
  .dd-r-grid{grid-template-columns:1fr 1fr;}
  .dd-grid-main{grid-template-columns:1fr;}
}
@media (max-width:900px){
  /* [REMOVAL-385] .dd-product__lockup{width:120px;} dropped: the topbar carries no logo (owner decision 8 Oct 2026) */
  .dd-split,.dd-mapsplit,.dd-zones{grid-template-columns:1fr;}
  /* a map box holds only its absolutely placed map, so it has no height of its own: stacked, each map takes a row of
     its own, under the History flights and above the other lists */
  .dd-split{grid-template-rows:minmax(0,1fr) minmax(240px,35%);}
  /* the flights list keeps room for its header and its tallest row whole below it (two long rule chips and "+12":
     198 px in fr with one flight, whose violations column the table leaves at its narrowest; 204 px of room under the
     54 px header); a short window scrolls the column to the list. The headings do not wrap, as in every other console
     table, so the header takes two lines in every locale */
  .dd-split__main{overflow-y:auto;}
  .dd-h-table{min-height:min(260px,100%);}
  .dd-h-table .data thead th{white-space:nowrap;}
  .dd-mapsplit,.dd-zones{grid-template-rows:minmax(240px,40%) minmax(0,1fr);}
  .dd-split__side,.dd-mapsplit__side{border-left:0; border-top:1px solid var(--border-subtle);}
  .dd-r-grid{grid-template-columns:1fr;}
  .dd-rs-grid{grid-template-columns:1fr;}
}
.dd-rail .rail__has:focus-within .rail__flyout{display:block;}

/* ------------------------------------------------------------ 11 collapsible rail */
/* dd-rail.js pins the rail open (.rail--x, 212 px, pushes the page) or collapses it (64 px);
   collapsed, it peeks open over the page (.rail--peek) without moving it. The brand is the
   dark lockup open and the full dark mark collapsed (the rail stays navy in both themes);
   the version sits in the middle of the rail's width in both states. */
.dd-rail{transition:width var(--dur-base) var(--ease), flex-basis var(--dur-base) var(--ease), margin-right var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);}
.dd-rail.rail--auto{z-index:var(--z-map-popover);}
.dd-rail.rail--peek{margin-right:calc(var(--space-8) - 212px); box-shadow:var(--elev-4);}
.dd-rail.rail--auto:not(.rail--x) .rail__has:hover .rail__flyout{display:none;}
body:has(.dd-rail.rail--x:not(.rail--peek)){--dd-rail-w:212px;}
.dd-rail .rail__has.dd-rail-brand,.dd-rail.rail--x .rail__has.dd-rail-brand{padding:0 0 0 10px;}
/* [REMOVAL-270] The brand box's width transition and its expanded width (the whole lockup) dropped: the mark keeps one
   size and place in both rail states */
.dd-rail .rail__has.rail__togglerow{top:12px;}
.dd-rail.rail--x .rail__has.rail__togglerow{top:23px;}
.dd-rail .rail__toggle{color:var(--dd-chrome-muted);}
.dd-rail .rail__toggle:hover{color:var(--dd-chrome-fg);}
.dd-rail .rail__toggle .ic{transition:transform var(--dur-base) var(--ease);}
.dd-rail:not(.rail--x) .rail__toggle .ic{width:18px; height:18px; filter:drop-shadow(0 1px 2px var(--sidebar-bg-bot)) drop-shadow(0 0 3px var(--sidebar-bg-bot));}
.dd-rail.rail--x:not(.rail--peek) .rail__toggle .ic{transform:rotate(180deg);}
/* long labels (EN "Building configuration") wrap instead of truncating */
.dd-rail.rail--x .rail__item{height:auto; min-height:40px; padding-top:var(--space-2); padding-bottom:var(--space-2);}
.dd-rail.rail--x .rail__item .rail__lbl{max-width:200px; min-width:0; flex:1 1 auto; white-space:normal; text-overflow:clip; overflow-wrap:anywhere; line-height:1.25;}
.dd-rail.rail--x .rail__inline-item{overflow-wrap:anywhere;}
.dd-rail.rail--x .dd-rail-badge{position:static; flex:0 0 auto;}
.dd-rail.rail--x .rail__sep:not([data-cap]){height:26px; padding:0 var(--space-3); gap:0;}
.dd-rail.rail--x .rail__sep:not([data-cap])::after{display:none;}
.dd-rail.rail--x .rail__foot{justify-content:center;}
@media (prefers-reduced-motion: reduce){
  /* [REMOVAL-271] .dd-rail-logo dropped from this list: the brand mark no longer animates */
  .dd-rail,.dd-rail .rail__lbl,.dd-rail .rail__toggle,.dd-rail .rail__toggle .ic,.dd-rail .rail__chev{transition:none;}
}
/* The live page (.dd-rail--fold) folds the rail below 1100 px (G54, the FOLD query of dd-rail.js). Until dd-rail.js
   swaps a pinned rail's classes, these rules give it the collapsed rail's width and look, so the first paint is
   already folded; the e2e journey compares the two element by element. Folded, the toggle closes the peek, so its
   chevron then points the way the pinned rail's does. */
@media (max-width:1099.98px){
  body:has(.dd-rail.dd-rail--fold.rail--x:not(.rail--peek)){--dd-rail-w:64px;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek){width:64px; flex-basis:64px; align-items:center;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__nav{align-items:center; padding-left:0; padding-right:0;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__nav > .rail__has{flex-direction:row; justify-content:center;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__has.rail__togglerow{top:12px; right:auto; left:8px; width:48px; height:50px; justify-content:center;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__toggle{width:46px; height:46px; border-radius:var(--radius-round); color:var(--dd-chrome-fg-strong); opacity:.85;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__toggle .ic{width:18px; height:18px; transform:none; filter:drop-shadow(0 1px 2px var(--sidebar-bg-bot)) drop-shadow(0 0 3px var(--sidebar-bg-bot));}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__item{width:42px; height:40px; min-height:0; padding:0; gap:0; justify-content:center; border-radius:11px;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__item.is-active{margin:0; color:var(--dd-chrome-fg-4); background:color-mix(in srgb,var(--accent) 16%,transparent); box-shadow:none;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__item.is-active::after{display:block;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__item .rail__lbl{max-width:0; opacity:0; white-space:nowrap;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__chev{width:18px; height:18px; opacity:1;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__sep{flex-direction:row; align-items:center; align-self:auto; padding:0;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__sep::before{width:40px; order:0; background:rgba(var(--dd-chrome-tint-rgb),.14);}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .dd-rail-badge{position:absolute;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .rail__foot{flex-direction:column; flex-wrap:nowrap; justify-content:flex-start; gap:var(--space-3); padding:10px 0 0; width:auto;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .dd-rail-mark{display:block;}
  .dd-rail.dd-rail--fold.rail--x:not(.rail--peek) .dd-rail-lockup{display:none;}
  /* Folded peek: keep the toggle in the 64 px column. The open rail puts it at right:8px; a click
     that closed the peek then left the pointer on the map, and the next hover opened it again
     before the next click closed it (G54). */
  .dd-rail.dd-rail--fold.rail--peek .rail__has.rail__togglerow{top:12px; right:auto; left:8px; width:48px; height:50px; justify-content:center;}
  .dd-rail.dd-rail--fold.rail--peek .rail__toggle{width:46px; height:46px; border-radius:var(--radius-round);}
  .dd-rail.dd-rail--fold.rail--peek .rail__toggle .ic{transform:rotate(180deg);}
}

/* ------------------------------------------------------------ 12 single sign-on */
/* Login page with single sign-on: the "Sign in with …" link leads; the local form (DD_LOCAL_LOGIN)
   follows under a captioned divider. Admin users table: organisation accounts carry a chip. */
.dd-login__or{display:flex; align-items:center; gap:10px; margin:var(--space-4) 0 var(--space-3); color:var(--text-muted); font-size:12px;}
.dd-login__or::before,.dd-login__or::after{content:""; flex:1 1 0; border-top:1px solid var(--border-default);}
.dd-login__or + .form-help{margin:-4px 0 var(--space-3);}
.dd-sso-chip{display:inline-block; margin-left:6px; padding:0 6px; border:1px solid var(--border-default); border-radius:var(--radius-sm); color:var(--text-secondary); font-size:11px; line-height:18px; vertical-align:middle;}
/* a user who also works for another organisation: the user dialog says why the account details are locked (R1-91b) */
.dd-u-shared{display:flex; align-items:center; gap:var(--space-2);}
.dd-u-shared .ic{width:14px; height:14px; flex:0 0 14px; color:var(--text-muted);}

/* ------------------------------------------------------------ 13 sensors & connections */
/* Admin > Sensors & connections. A state pill carries an icon per state instead of the status dot (shape +
   text + colour); the connection test lists each check with an icon; a stored password shows as set, never
   as a value. No lime: a connection state is system state, not a live signal. */
.dd-conn{margin-bottom:var(--space-4);}
.dd-conn .card__bd > .form-help{margin:0 0 10px;}
.dd-feedalert{box-shadow:inset 4px 0 0 var(--dd-fa, var(--border-strong));} /* a feed alert is a system state: status colours and the connection pills' icons (G12) */
.dd-feedalert > .ic{flex:0 0 14px; width:14px; height:14px; margin-top:2px; color:var(--dd-fa, var(--text-muted));}
.dd-feedalert[data-status="ok"]{--dd-fa:var(--status-ok-fg);} .dd-feedalert[data-status="warn"]{--dd-fa:var(--status-warn-fg);} .dd-feedalert[data-status="error"]{--dd-fa:var(--status-error-fg);}
.status-pill.dd-state{white-space:nowrap;}
.status-pill.dd-state::before{display:none;}
.dd-state .ic{width:12px; height:12px; flex:0 0 12px;}
.dd-c-warn{display:flex; align-items:center; gap:var(--space-1); margin-top:var(--space-1); color:var(--status-warn-fg); font-size:11.5px;}
.dd-c-warn .ic{width:12px; height:12px; flex:0 0 12px;}
.data td .switch{display:inline-block; vertical-align:middle;}
.dd-cform .dd-grid2{margin:var(--space-1) 0 10px;}
.dd-cform .dd-span2{grid-column:1 / -1;}
.dd-cform .form-control[aria-invalid="true"]{border-color:var(--status-error-fg);}
.dd-pem{min-height:88px; font-size:12px; resize:vertical;}
.dd-secret{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; padding:6px 10px; border:1px dashed var(--border-default); border-radius:var(--radius-md); color:var(--text-secondary); font-size:13px;}
.dd-secret .ic{width:14px; height:14px; flex:0 0 14px;}
.dd-secret .btn{margin-left:auto;}
.dd-secret + .form-control{margin-top:6px;}
.dd-ctest{margin-top:var(--space-3); padding:10px var(--space-3); border:1px solid var(--border-default); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-ctest__hd{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;}
.dd-ctest__hd .ic{width:16px; height:16px; flex:0 0 16px;}
.dd-ctest[data-status="ok"] .dd-ctest__hd .ic{color:var(--status-ok-fg);}
.dd-ctest[data-status="error"] .dd-ctest__hd .ic{color:var(--status-error-fg);}
.dd-checks{list-style:none; margin:var(--space-2) 0 0; padding:0; display:grid; gap:var(--space-1);}
.dd-checks li{display:flex; align-items:center; gap:var(--space-2); font-size:13px;}
.dd-checks .ic{width:14px; height:14px; flex:0 0 14px;}
.dd-checks [data-ok="true"] .ic{color:var(--status-ok-fg);}
.dd-checks [data-ok="false"] .ic{color:var(--status-error-fg);}
.dd-checks [data-ok="none"] .ic{color:var(--text-muted);}
.dd-checks__v{margin-left:auto; color:var(--text-secondary); font-size:12px;}

/* ------------------------------------------------------------ 14 event summary bar and event queue (R1-31) */
/* The summary bar takes the card strip's place and geometry, so the tools, legend and panels below keep their
   offsets. Counts are aria-live="off" (the critical toast announces critical events). Severity is shape + colour;
   lime only marks "happening now" (a live signal). The queue shares the track detail's column: a drone opened
   from the queue covers it (.has-detail) until "Back to event queue". */
.dd-evsum{position:absolute; top:var(--dd-gap); left:calc(var(--dd-lp-w) + 2 * var(--dd-gap)); right:var(--dd-gap); height:54px; display:flex; align-items:stretch;
  container:dd-evsum / inline-size;
  background:color-mix(in srgb,var(--surface-0) 94%,transparent); backdrop-filter:blur(10px); border:1px solid var(--border-subtle); border-radius:var(--radius-lg); box-shadow:var(--elev-3); overflow:hidden;}
/* the bar keeps its 54 px: below 1240 px (French needs 1207 px for the chevron, the title, the counts, one full 15rem
   event and Acknowledge) the title is for screen readers only, as the first event never shrinks and would push
   Acknowledge out */
.dd-evsum__hd{flex:0 0 auto; padding:0 var(--space-4); border-right:1px solid var(--border-subtle);}
/* [REMOVAL-393] max-width: 1200px raised to 1240px: the chevron that folds the bar (owner decision 8 Oct 2026) takes
   32 px, which brings French past 1200 px */
@container dd-evsum (max-width: 1240px){ .dd-evsum__hd{position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;} }
/* every count is a number over its caption, so the most urgent event keeps its width in the longer languages */
.dd-evsum__tot{display:flex; align-items:center; gap:10px; padding:0 14px; border:0; border-right:1px solid var(--border-subtle); background:var(--surface-1);
  color:var(--text-muted); white-space:nowrap;}
.dd-evsum__tot:hover{background:var(--surface-2); color:var(--text-secondary);}
.dd-evsum__tot .ic{width:16px; height:16px; color:var(--text-secondary);}
.dd-evsum__st{display:flex; flex-direction:column; align-items:flex-start; gap:2px;}
.dd-evsum__tot b{font-size:15px; font-weight:800; line-height:1.1; color:var(--text-primary);}
.dd-evsum[data-critical="true"] .dd-evsum__tot{box-shadow:inset 3px 0 0 var(--sev-critical);} .dd-evsum .dd-evsum__tot:focus-visible{outline:2px solid var(--accent); outline-offset:-2px; box-shadow:none;} .dd-evsum[data-critical="true"] .dd-evsum__tot:focus-visible{box-shadow:inset 3px 0 0 var(--sev-critical);} /* inset: the total fills the bar's height, so the bar clips an outer ring */
.dd-evsum[data-critical="true"] .dd-evsum__tot .ic{color:var(--sev-critical-ink);}
.dd-evsum__counts{display:flex; align-items:center; gap:2px; padding:0 6px; border-right:1px solid var(--border-subtle);}
.dd-evsum__c{display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:2px; height:42px; padding:0 var(--space-2); border:0;
  border-radius:var(--radius-md); background:none; color:var(--text-muted); white-space:nowrap;}
.dd-evsum__c:hover{background:var(--surface-2); color:var(--text-secondary);}
.dd-evsum__c b{font-size:14px; font-weight:700; line-height:1.1; color:var(--text-primary);}
.dd-evsum__l{display:flex; align-items:center; gap:5px; font-size:10.5px; font-weight:700; line-height:1.2; letter-spacing:.04em; text-transform:uppercase;}
.dd-evsum__l .ic{width:12px; height:12px;}
.dd-evsum__l .shp{width:10px; height:10px;}
.dd-evsum__top{flex:1; min-width:0; display:flex; align-items:center; gap:6px; padding:0 6px 0 var(--space-2); overflow:hidden;}
.dd-evsum__ev{flex:0 0 auto; width:auto; max-width:15rem; min-width:0; display:flex; align-items:center; gap:9px; height:40px; padding:0 10px; border:1px solid color-mix(in srgb,var(--c) 45%,var(--border-subtle));
  border-radius:9px; background:color-mix(in srgb,var(--c) 7%,var(--surface-1)); color:inherit; text-align:left;}
.dd-evsum__ev:hover{background:var(--surface-2);}
.dd-evsum__ev[hidden]{display:none;}
.dd-evsum__shp{width:13px; height:13px; flex:0 0 13px;}
.dd-evsum__evbd{display:flex; flex-direction:column; min-width:0; line-height:1.25;}
.dd-evsum__evbd b{font-size:12px; color:var(--text-primary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
/* [REMOVAL-313] .dd-evsum__evbd span stacked chip line was briefly a tape; chips hug content again */
.dd-evsum__evbd span{font-size:11px; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dd-evsum__ack.btn-icon{width:32px; height:32px; flex:0 0 32px;}
/* [REMOVAL-419] .dd-evsum__clear ("No open events") replaced by .dd-att__quiet, the attention bar's quiet line */
.dd-evsum__q{align-self:center; margin:0 var(--space-2) 0 2px; white-space:nowrap;}
.dd-evsum__q[aria-expanded="true"]{background:var(--accent-soft); border-color:transparent; color:var(--accent-active);}
/* a narrow bar (about 1280 px screens) keeps the queue button as its icon; its name stays in aria-label and title */
@container dd-evsum (max-width: 800px){ .dd-evsum__ql{display:none;} }
/* the chevron at the bar's left end folds it to compact (owner decision 8 Oct 2026) and stays in place, so a second
   click opens it again. Compact keeps the open total, the events happening now, the critical ones and the queue button,
   each a symbol and a number whose caption stays for screen readers. The bar hugs them: an inline-size container would
   size it to nothing, so it states its narrow-bar rules itself. A new critical event leaves it compact (its toast and
   the critical count tell) */
.dd-evsum__fold{flex:0 0 auto; display:flex; align-items:center; justify-content:center; width:32px; padding:0; border:0; border-right:1px solid var(--border-subtle);
  background:none; color:var(--text-muted);}
.dd-evsum__fold:hover{background:var(--surface-2); color:var(--text-secondary);}
.dd-evsum__fold .ic{width:16px; height:16px; transform:rotate(180deg);}
.dd-evsum .dd-evsum__fold:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;}
.dd-evsum--compact{right:auto; container-type:normal;}
.dd-evsum--compact .dd-evsum__fold .ic{transform:none;}
.dd-evsum--compact :is(.dd-evsum__top, .dd-att__old, .dd-evsum__ql){display:none;}
.dd-evsum--compact :is(.dd-evsum__hd, .dd-evsum__lt){position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;}
.dd-evsum--compact .dd-evsum__st{gap:0;}
.dd-evsum--compact .dd-evsum__c{flex-direction:row-reverse; align-items:center; gap:var(--space-1);}
.dd-evsum--compact .dd-evsum__q{margin-left:var(--space-2);}

/* ------------------------------------------------ attention bar (the event summary bar's slot) */
.dd-att__more{flex:0 0 auto; display:inline-flex; align-items:center; gap:var(--space-1); height:30px; padding:0 var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-pill); background:none;
  color:var(--text-secondary); font-size:12px; font-weight:700; white-space:nowrap;}
.dd-att__more:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-att__quiet{flex:1; min-width:0; display:flex; align-items:center; gap:var(--space-2); padding:0 var(--space-3); color:var(--text-muted); font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dd-att__quiet .ic{width:15px; height:15px; color:var(--status-ok-fg);}
.dd-att__old{flex:0 1 auto; min-width:0; display:flex; align-items:center; gap:var(--space-2); padding:0 var(--space-3); border:0; border-left:1px solid var(--border-subtle); background:none; cursor:pointer; color:var(--text-muted); font-size:11.5px; white-space:nowrap; text-decoration:none;}
.dd-att__old[hidden]{display:none;}
.dd-att__old:hover{color:var(--text-secondary); background:var(--surface-1);} .dd-evsum .dd-att__old:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* inset: the button fills the bar's height, so the bar clips an outer ring */
.dd-att__old b{font-family:var(--font-mono); font-weight:700; color:var(--text-secondary);}
.dd-att__old .ic{width:13px; height:13px;}
.dd-evsum[data-quiet="true"] .dd-evsum__tot{box-shadow:none;}
.dd-evsum[data-quiet="true"] .dd-evsum__tot b{color:var(--text-muted);}
.dd-evsum__c[data-zero="true"] b,.dd-evsum__c[data-zero="true"]{color:var(--text-disabled);}
.dd-evsum__ev--group .dd-evsum__shp{width:15px; height:15px; flex-basis:15px;}
.dd-evsum__top .dd-evsum__ev{flex:0 1 15rem; min-width:8rem;} /* shrinks in a narrow bar instead of pushing Acknowledge out */
.dd-evsum__top > :is(.dd-evsum__ack,.dd-att__more){flex-shrink:0;}
/* the words follow the number after a gap: no leading space in the translated text */
.dd-att__oldtxt,.dd-att__moretxt{margin-left:var(--space-1);}
@container dd-evsum (max-width: 1180px){ .dd-att__oldtxt{display:none;} .dd-att__old{padding:0 var(--space-2);} .dd-evsum__c{padding:0 var(--space-2);} }
/* a narrow bar (about 1440 px screens) keeps each severity as its shape over its number: the caption stays for screen readers,
   so the lead drone, its Acknowledge button and "+N" still fit */
@container dd-evsum (max-width: 900px){ .dd-evsum__counts .dd-evsum__lt{position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;} }
@container dd-evsum (max-width: 1040px){ .dd-att__moretxt{display:none;} .dd-att__more{padding:0 var(--space-2);} .dd-evsum__counts{padding:0 2px;} }

/* event queue: right column, the track detail's slot and width */
.dd-evq{position:absolute; top:calc(var(--dd-gap) + 66px); right:var(--dd-gap); bottom:var(--dd-gap); width:var(--dd-detail-w); display:flex; flex-direction:column; overflow:hidden;}
.dd-live-view.has-detail .dd-evq{visibility:hidden;}
.dd-live-view.has-evq .dd-tools{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap));}
.dd-live-view.has-evq .dd-legend{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap) + 52px);}
.dd-live-view.has-evq .dd-statusbar{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap));}
/* [REMOVAL-275] .dd-live-view.has-evq .dd-pb dropped: beside the event queue the playback docks under it (section 4, G51) */
.dd-evq__hd{display:flex; flex-direction:column; gap:var(--space-2); padding:10px 10px 10px 14px; border-bottom:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-evq__title{display:grid; grid-template-columns:minmax(0,1fr) auto; column-gap:var(--space-2); row-gap:2px; align-items:center;}
.dd-evq__title h2{margin:0; display:flex; align-items:center; gap:var(--space-2); font-size:14.5px; font-weight:800; color:var(--text-primary); white-space:nowrap; border-radius:4px;}
.dd-evq__title h2 .ic{width:16px; height:16px; color:var(--text-secondary);}
.dd-evq__title h2:focus{outline:none;}
.dd-evq__title h2:focus-visible{box-shadow:var(--focus-ring);}
.dd-evq__sub{grid-column:1; font-size:11.5px; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0;}
.dd-evq__title .win__ctl{grid-column:2; grid-row:1 / 3;}
.dd-evq__stale{display:flex; align-items:flex-start; gap:var(--space-2); padding:var(--space-2) 10px; border-radius:var(--radius-md); font-size:12px;
  background:var(--status-error-bg); border:1px solid var(--status-error-bd); color:var(--status-error-fg);}
.dd-evq__stale .ic{width:14px; height:14px; flex:0 0 14px; margin-top:2px;}
.dd-evq__stale div{display:flex; flex-direction:column; gap:2px;}
.dd-evq__stale b{color:var(--text-primary);} .dd-evq__stale span{color:var(--text-secondary);}
.dd-evq__state{display:flex;}
.dd-evq__state button{flex:1 1 auto; min-width:0; padding:5px 6px; font-size:12px; line-height:1.2; overflow-wrap:anywhere;}
.dd-evq__quick,.dd-evq__row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;}
.dd-evq__sev{display:flex; flex-wrap:wrap; gap:var(--space-1);}
.dd-evq__now{margin-left:auto; font-size:12px; white-space:nowrap;}
.dd-evq__now .livedot{flex:0 0 7px;}
.dd-evq__morebtn{display:flex; align-items:center; gap:7px; height:30px; padding:0 10px; border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  background:var(--surface-0); color:var(--text-secondary); font-size:12.5px; font-weight:700; white-space:nowrap;}
.dd-evq__morebtn:hover{color:var(--text-primary); border-color:var(--border-default);}
.dd-evq__morebtn .ic{width:14px; height:14px;}
.dd-evq__morebtn[aria-expanded="true"] .dd-filters__chev{transform:rotate(180deg);}
.dd-evq__group{display:flex; align-items:center; gap:6px; margin-left:auto; min-width:0; font-size:12px; color:var(--text-muted); white-space:nowrap;}
.dd-evq__group .form-select{height:30px; font-size:12.5px; min-width:0; max-width:190px;}
.dd-evq .dd-evf{max-height:40vh; overflow:auto; padding:2px 2px 0; border-top:1px solid var(--border-subtle);}
.dd-evq__track{display:flex; align-items:center; gap:6px; align-self:flex-start; max-width:100%; padding:2px 2px 2px 10px; border-radius:var(--radius-pill);
  background:var(--accent-soft); color:var(--accent-active); font-size:12px; font-weight:600;}
.dd-evq__track > span{white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0;}
.dd-evq__track > .ic{width:14px; height:14px; flex:0 0 14px;}
.dd-evq__track .btn-icon{width:24px; height:24px; flex:0 0 24px;}
.dd-evq__pill{display:flex; align-items:center; justify-content:center; gap:6px; margin:var(--space-2) var(--space-3) 0; padding:5px var(--space-3); border:0; border-radius:var(--radius-pill);
  background:var(--accent); color:var(--on-accent); font-size:12px; font-weight:700; box-shadow:var(--elev-1);}
.dd-evq__pill .ic{width:13px; height:13px;}
.dd-evq__bd{flex:1; min-height:0; overflow:auto; padding:var(--space-1) 6px 10px;}
.dd-evq .dd-evq__bd:focus-visible{outline:2px solid var(--accent); outline-offset:-2px;} /* [REMOVAL-180] .dd-evq__bd:focus{outline:none;} replaced: the global :focus-visible ring beat it and fell outside the list, where the panel clips it; this ring is inset, and .dd-evq lifts it to the global rule's weight, which this later file wins */
.dd-evq__ft{display:flex; justify-content:center; padding:6px 10px; border-top:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-evq__ft .btn .ic{width:14px; height:14px;}
/* groups */
.dd-evg{margin-top:var(--space-1);}
.dd-evg__hd{display:flex; align-items:stretch; gap:2px; margin:0; font-size:inherit;}
.dd-evg__toggle{flex:1; min-width:0; display:flex; align-items:center; gap:7px; padding:7px var(--space-2); border:0; border-radius:7px; background:none; color:var(--text-secondary);
  font-size:12.5px; font-weight:700; text-align:left;}
.dd-evg__toggle:hover{background:var(--surface-1); color:var(--text-primary);}
.dd-evg__toggle > .ic{width:14px; height:14px; flex:0 0 14px; color:var(--text-muted);}
.dd-evg__name{flex:1; min-width:0; overflow-wrap:anywhere;}
.dd-evg__counts{display:flex; align-items:center; gap:var(--space-2); flex:0 0 auto;}
.dd-evg__now,.dd-evg__crit{display:inline-flex; align-items:center; gap:var(--space-1); font:700 11.5px var(--font-mono);}
.dd-evg__now{color:var(--live-ink);}
.dd-evg__n{font-size:11px; color:var(--text-secondary); background:var(--surface-2); border-radius:9px; padding:1px 7px;}
.dd-evg__menu,.dd-evr__more{width:28px; flex:0 0 28px; border:0; border-radius:7px; background:none; color:var(--text-muted);}
.dd-evg__menu:hover,.dd-evr__more:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-evg__menu .ic,.dd-evr__more .ic{width:16px; height:16px;}
.dd-evg__rows{list-style:none; margin:2px 0 0; padding:0;}
.dd-evg__none,.dd-evg__wait{padding:6px 10px var(--space-2) 30px; font-size:12px; color:var(--text-disabled);}
.dd-evg__more{display:flex; align-items:center; gap:6px; margin:2px 0 var(--space-1) 22px; font-size:12px;}
.dd-evg__more .ic{width:13px; height:13px;}
.dd-evg__more .dd-muted-sm{margin-left:2px;}
/* rows: what (rule), who (drone, LIVE while airborne), age and state; Acknowledge in a fixed slot (DESIGN-SYSTEM §4.4.1) */
.dd-evr{display:flex; align-items:center; gap:2px; margin:2px 0; border-radius:9px; background:var(--surface-0); border:1px solid var(--border-subtle);}
.dd-evr:hover{background:var(--surface-1);}
.dd-evr[data-state="open"]{border-color:color-mix(in srgb,var(--c) 40%,var(--border-subtle));}
.dd-evr[data-handled="true"]{opacity:.55;}
.dd-evr__main{flex:1; min-width:0; display:flex; align-items:flex-start; gap:var(--space-2); padding:7px var(--space-1) 7px var(--space-3); border:0; background:none; color:inherit; text-align:left; border-radius:9px;}
.dd-evr__shp{flex:0 0 13px; display:flex; margin-top:3px;}
.dd-evr__shp .shp{width:13px; height:13px;}
.dd-evr__bd{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px;}
.dd-evr__t{font-size:12.5px; font-weight:700; line-height:1.3; color:var(--text-primary); overflow-wrap:anywhere;}
.dd-evr__s{display:flex; align-items:center; gap:5px; min-width:0; font-size:11px; color:var(--text-secondary); white-space:nowrap;}
.dd-evr__s > span{overflow:hidden; text-overflow:ellipsis; min-width:0;}
.dd-evr__s .livedot{flex:0 0 7px;}
.dd-evr__s .dd-mono{color:var(--text-muted); flex:0 1 auto; font-size:10.5px;}
.dd-evr__m{flex:0 0 auto; display:flex; flex-direction:column; align-items:flex-end; gap:3px; font-size:11px; color:var(--text-muted);}
.dd-evr__m .status-pill{padding:0 6px; font-size:10.5px;}
.dd-evr__owner{display:inline-flex; align-items:center; gap:3px; max-width:92px; font-size:11px; color:var(--text-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.dd-evr__owner .ic{width:12px; height:12px; flex:0 0 12px;}
.dd-evr__acts{display:flex; align-items:center; gap:2px; padding-right:var(--space-1); align-self:stretch;}
.dd-evr__ack.btn-icon{width:30px; height:30px; flex:0 0 30px; align-self:center;}
.dd-evr__more{align-self:stretch; margin:var(--space-1) 0;}
.dd-evr__main:focus-visible,.dd-evg__toggle:focus-visible,.dd-evg__menu:focus-visible,.dd-evr__more:focus-visible,.dd-evsum__c:focus-visible,
.dd-evsum__tot:focus-visible,.dd-evsum__ev:focus-visible,.dd-trow__ev:focus-visible,.dd-evq__morebtn:focus-visible,.dd-sevchip:focus-visible,.dd-detail__back:focus-visible{outline:none; box-shadow:var(--focus-ring);}
/* track detail: back to the queue; the event opened from the queue */
.dd-detail__back{display:inline-flex; align-items:center; gap:var(--space-1); margin:0 0 var(--space-2) -6px; padding:3px var(--space-2) 3px var(--space-1); border:0; border-radius:var(--radius-sm); background:none;
  color:var(--accent); font-size:12px; font-weight:700;}
.dd-detail__back:hover{background:var(--accent-soft);}
.dd-detail__back .ic{width:14px; height:14px;}
.dd-flip{transform:scaleX(-1);}
.dd-evrow[aria-current="true"]{background:var(--accent-soft); border-radius:var(--radius-sm); box-shadow:inset 4px 0 0 var(--c), 0 0 0 1px color-mix(in srgb,var(--accent) 45%,transparent);}
/* threat tree: open events of a drone (opens the queue filtered to it), stacked above the actions button so the
   drone name and its list chip keep their width */
.dd-trow__side{display:flex; flex-direction:column; align-items:center; gap:2px; padding:var(--space-1) 2px var(--space-1) 0;}
.dd-trow__side > .dd-trow__more{flex:1 1 auto; min-height:22px; margin:0;}
.dd-trow__ev{display:inline-flex; align-items:center; gap:2px; height:24px; padding:0 5px; border:1px solid var(--border-default); border-radius:var(--radius-pill);
  background:var(--surface-1); color:var(--text-secondary); font-size:11px;}
.dd-trow__ev .ic{width:11px; height:11px;}
.dd-trow__ev:hover{border-color:var(--border-strong); color:var(--text-primary);}
.dd-trow__ack{padding:0 var(--space-1);}
.dd-trow__ev[data-new="true"]{background:var(--accent-soft); border-color:transparent; color:var(--accent-active); font-weight:700;}
/* severity chips (shape + colour + label, with the count) and the "More filters" panel, shared with the Events page */
.dd-sevchip{display:inline-flex; align-items:center; gap:5px; height:28px; padding:0 var(--space-2); border:1px solid var(--border-default); border-radius:var(--radius-pill);
  background:var(--surface-0); font-size:12px; font-weight:600; white-space:nowrap;}
.dd-sevchip:hover{border-color:var(--border-strong);}
.dd-sevchip b{font-size:11.5px; font-weight:700; color:var(--text-primary);}
.dd-sevchip span{color:var(--text-secondary);}
.dd-sevchip .shp{width:12px; height:12px;}
.dd-sevchip[aria-pressed="true"]{background:color-mix(in srgb,var(--c) 16%,var(--surface-0)); border-color:color-mix(in srgb,var(--c) 70%,var(--border-default)); box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--c) 70%,transparent);}
.dd-sevchip[aria-pressed="true"] span{color:var(--text-primary);}
.dd-evf{display:flex; flex-direction:column; gap:var(--space-1);}
.dd-evf__dim{margin:0; padding:6px 0 var(--space-1); border:0; min-width:0;}
.dd-evf__dim legend{padding:0 0 3px; font-size:10.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted);}
.dd-evf__opt{display:flex; align-items:center; gap:7px; padding:3px 6px; border-radius:var(--radius-sm); font-size:12.5px; color:var(--text-secondary); cursor:pointer;}
.dd-evf__opt:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-evf__opt input{flex:0 0 auto; margin:0;}
.dd-evf__opt .ic{width:13px; height:13px; flex:0 0 13px; color:var(--text-muted);}
.dd-evf__name{flex:1; min-width:0; overflow-wrap:anywhere;}
.dd-evf__n{flex:0 0 auto; font-size:11px; color:var(--text-muted);}
.dd-evf__none{margin:0; padding:3px 6px; font-size:12px; color:var(--text-disabled);}
.dd-evf__all{margin:2px 0 0; font-size:12px;}
.dd-evf__ft{display:flex; justify-content:flex-end; padding:2px 0 6px;}
.dd-evf__ft .btn .ic{width:13px; height:13px;}
/* group actions and Events page selection: confirmation with progress */
.dd-bulk__n{margin:0 0 10px; font-weight:600; color:var(--text-primary);}
.dd-bulk__run{margin-top:var(--space-2);}
.dd-bulk__txt{margin:6px 0 0;}
/* Events page: severity chips, More filters, selection, bulk bar, Load more */
.dd-e-sev{display:flex; gap:var(--space-1); flex-wrap:wrap;}
.dd-e-sev .dd-sevchip{height:32px; padding:0 10px;}
.dd-e-now{align-self:flex-end; height:34px; white-space:nowrap;}
.dd-e-morebtn{align-self:flex-end; height:34px; white-space:nowrap;}
.dd-e-morebtn[aria-expanded="true"]{background:var(--accent-soft); border-color:transparent; color:var(--accent-active);}
.dd-e-morebtn .dd-filters__n{margin-left:2px;}
/* a track number is short: its field gives way before the search beside it, so the bar keeps its lines at 1024 px */
.dd-filterbar .dd-e-track{min-width:140px;}
.dd-e-more{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--space-1) 18px; padding:var(--space-2) 14px var(--space-1); margin:-4px 0 var(--space-3);}
.dd-e-more .dd-evf__ft{grid-column:1 / -1;}
.dd-evtable .dd-e-selc{width:36px; padding-right:0;}
.dd-evtable tr[aria-current="true"] td{background:var(--accent-soft);}
.dd-e-bulk{position:sticky; top:0; z-index:2; flex-wrap:wrap; gap:var(--space-2) var(--space-3); padding:var(--space-2) var(--space-3); font-size:12.5px;}
.dd-e-bulk__acts{display:flex; gap:6px; flex-wrap:wrap;}
.dd-e-foot{display:flex; justify-content:center; padding:var(--space-3) 0 var(--space-1);}
@media (prefers-reduced-motion: reduce){
  .dd-evq__morebtn .dd-filters__chev,.dd-live-view .dd-tools,.dd-live-view .dd-legend,.dd-live-view .dd-statusbar{transition:none;}
}

/* sensor coverage (R1-31): per-sensor choice in the sensor dialog, default radius per type in the side column */
.dd-side-stack{display:flex; flex-direction:column; gap:var(--space-4);}
.dd-side-stack > .card{margin:0;}
#dd-covdef .card__bd > .form-help{margin:0 0 10px;}
#dd-covdef .field{margin-bottom:10px;}
/* [REMOVAL-661] .dd-cell-cov{white-space:nowrap} dropped: the coverage text wraps before its distance, which keeps its
   number and unit together, so the sensors table fits beside the side column */
/* the sensors table fits beside the side column at 1440 x 900 with the side menu pinned open, in every locale (G08):
   8 px cell padding (.dd-data-tight), headers that wrap, and how long ago a sensor was last seen under the time,
   wrapping (after a day it is a date and time) */
#dd-s-table thead th{white-space:normal;}
#dd-s-table td.dd-mono .dd-muted-sm{white-space:normal;}
.dd-covmode{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:6px; margin-bottom:var(--space-3);}
.dd-covmode .dd-contact{align-items:flex-start;}
.dd-covmode .dd-contact__bd span{white-space:normal;}
@media (max-width:640px){ .dd-covmode{grid-template-columns:1fr;} }
.dd-covmap{height:280px; border:1px solid var(--border-subtle); border-radius:var(--radius-md); overflow:hidden;}
.dd-cov-area__bar{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:var(--space-2); min-height:30px;}
.dd-covsensor{stroke:var(--surface-0); stroke-width:2; fill:var(--text-primary); fill-opacity:1;}
.dd-modal .dd-unit .form-control[aria-invalid="true"]{border-color:var(--status-error-fg);}

/* ------------------------------------------------------------ 15 control areas (R1-23) */
/* Drawn on the live map by every role. The panel takes the right column (the track detail's slot and width) and
   covers the detail and the event queue while it is open. The area keeps its own magenta family (--zone-control-*);
   only the preset cards show a severity, with its shape and colour, because that is the event the area raises. */
.dd-ca{position:absolute; top:calc(var(--dd-gap) + 66px); right:var(--dd-gap); bottom:var(--dd-gap); width:var(--dd-detail-w); display:flex; flex-direction:column; overflow:hidden; z-index:calc(var(--z-dd-panel) + 2);}
.dd-live-view.has-ca .dd-detail,.dd-live-view.has-ca .dd-evq{visibility:hidden;}
.dd-live-view.has-ca .dd-tools,.dd-live-view.has-ca .dd-statusbar{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap));}
/* [REMOVAL-229] .dd-live-view.has-ca .dd-pb moved from the tool rail's rule above to the legend's rule below: the
   playback ends left of the tool rail's column, as the legend does (G49) */
.dd-live-view.has-ca .dd-legend{right:calc(var(--dd-detail-w) + 2 * var(--dd-gap) + 52px);} /* [REMOVAL-276] ,.dd-live-view.has-ca .dd-pb dropped from this rule: beside a control area the playback docks under it (section 4, G51) */
.dd-live-view .dd-drawhint{top:calc(var(--dd-gap) + 66px); left:calc(50% + (var(--dd-lp-w) - var(--dd-detail-w)) / 2);}
.dd-ca__form{flex:1; min-height:0; display:flex; flex-direction:column;}
.dd-ca__hd{padding:10px 10px 10px 14px; border-bottom:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-ca__title{display:flex; align-items:center; gap:var(--space-2);}
.dd-ca__title h2{flex:1; min-width:0; margin:0; display:flex; align-items:center; gap:var(--space-2); font-size:14.5px; font-weight:800; color:var(--text-primary); border-radius:4px;}
.dd-ca__title h2 .ic{width:16px; height:16px; flex:0 0 16px; color:var(--zone-control-stroke);}
.dd-ca__title h2:focus{outline:none;}
.dd-ca__title h2:focus-visible{box-shadow:var(--focus-ring);}
.dd-ca__sub{margin:3px 0 0; font-size:11.5px; color:var(--text-muted);}
.dd-ca__bd{flex:1; overflow:auto; padding:var(--space-3) 14px var(--space-1);}
.dd-ca__bd > .form-help{margin:0 0 var(--space-3);}
.dd-ca__fs{border:0; margin:0; padding:0; min-width:0;}
.dd-ca .field{margin-bottom:10px;}
.dd-ca .form-check{margin-bottom:6px;}
.dd-ca__presets{display:grid; grid-template-columns:1fr; gap:6px; margin-bottom:10px;}
.dd-ca__presets .dd-contact{align-items:flex-start;}
.dd-ca__presets .dd-contact__bd span{white-space:normal;}
.dd-ca__presets .shp{width:14px; height:14px; flex:0 0 14px; margin-top:2px;}
.dd-ca__weights{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:2px var(--space-3);}
.dd-ca__ro{display:flex; align-items:flex-start; gap:var(--space-2); margin:0 0 var(--space-3); padding:var(--space-2) 10px; border-radius:var(--radius-md); background:var(--surface-1); font-size:12.5px; color:var(--text-secondary);}
.dd-ca__ro .ic{width:15px; height:15px; flex:0 0 15px; margin-top:1px; color:var(--text-muted);}
.dd-ca__fs:disabled .dd-contact{cursor:default;}
.dd-ca__ft{display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:var(--space-2); padding:10px 14px; border-top:1px solid var(--border-subtle); background:var(--surface-1);}
.dd-ca [aria-invalid="true"]{border-color:var(--status-error-fg);}
.dd-z-note{margin:0 0 10px;}
/* keyboard drawing and import (R1-23): the key help, typed coordinates, the import preview and the map crosshair */
.dd-ca__live{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;}
.dd-polystate__st{display:flex; flex-wrap:wrap; align-items:center; gap:6px;}
.dd-ca__draw{margin-top:var(--space-2);}
.dd-ca__draw > .form-help{margin:0;}
.dd-ca__kbtns{display:flex; flex-wrap:wrap; gap:6px; margin:var(--space-2) 0 10px;}
.dd-ca__keys{list-style:none; margin:var(--space-1) 0 0; padding:0; display:grid; gap:var(--space-1); font-size:12px; color:var(--text-secondary);}
.dd-ca__keys li{display:grid; grid-template-columns:minmax(7.5em, max-content) minmax(0,1fr); gap:var(--space-1) 10px; align-items:baseline;}
.dd-ca__k{display:inline-flex; flex-wrap:wrap; gap:3px; align-items:baseline; color:var(--text-muted);}
.dd-ca__more{margin:10px 0 0; padding:6px 10px; border:1px solid var(--border-subtle); border-radius:var(--radius-md);}
.dd-ca__more > summary{display:flex; align-items:center; gap:6px; padding:2px 0; cursor:pointer; font-size:12.5px; font-weight:700; color:var(--text-primary); border-radius:4px;}
.dd-ca__more > summary .ic{width:14px; height:14px; flex:0 0 14px;}
.dd-ca__more > summary:focus{outline:none;}
.dd-ca__more > summary:focus-visible{box-shadow:var(--focus-ring);}
.dd-ca__more[open] > summary{margin-bottom:var(--space-2);}
.dd-ca__import{margin:0 0 var(--space-3);}
.dd-ca__msg{margin:6px 0 0; font-size:12px; color:var(--text-secondary);}
.dd-ca__msg:empty{display:none;}
.dd-ca__msg.is-warn{color:var(--status-error-fg);}
.dd-ca__cands{margin-top:var(--space-2);}
.dd-ca__clist{list-style:none; margin:var(--space-1) 0 var(--space-2); padding:0; display:grid; gap:6px;}
.dd-ca__cand{padding:var(--space-2) 10px; border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-ca__cand.is-used{border-color:var(--border-focus);}
.dd-ca__cand-hd{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:6px; font-size:12.5px; color:var(--text-primary); overflow-wrap:anywhere;}
.dd-ca__cand-hd .status-pill .ic{width:11px; height:11px;}
.dd-ca__cand-meta{margin:2px 0 0; font-size:11.5px; color:var(--text-muted); overflow-wrap:anywhere;}
.dd-ca__warns{list-style:none; margin:6px 0; padding:0; display:grid; gap:var(--space-1); font-size:12px; color:var(--text-secondary);}
.dd-ca__warns li{display:flex; gap:6px; align-items:flex-start; overflow-wrap:anywhere;}
.dd-ca__warns .ic{width:13px; height:13px; flex:0 0 13px; margin-top:2px; color:var(--status-warn-fg);}
.dd-importpoly{stroke:var(--zone-control-stroke); stroke-width:2; stroke-dasharray:3 5; fill:var(--zone-control-stroke); fill-opacity:.06;}
/* the map fills the live view, so the view's centre is the point Enter places */
.dd-crosshair{position:absolute; left:50%; top:50%; width:32px; height:32px; margin:-16px 0 0 -16px; pointer-events:none; z-index:var(--z-map-overlay);}
.dd-crosshair[hidden]{display:none;}
.dd-crosshair::before,.dd-crosshair::after{content:""; position:absolute; background:var(--text-primary); box-shadow:0 0 0 1px var(--surface-0);}
.dd-crosshair::before{left:15px; top:0; width:2px; height:32px;}
.dd-crosshair::after{left:0; top:15px; width:32px; height:2px;}
.dd-crosshair span{position:absolute; left:9px; top:9px; width:14px; height:14px; border:2px solid var(--text-primary); border-radius:var(--radius-round); box-shadow:0 0 0 1px var(--surface-0);}
/* the list of control areas (G35) in the same panel: each entry opens its area as a click on the map does. The event
   is severity shape, ink and label on surface-1; "View only" marks an area the user may not change. Pretty wrapping
   keeps a lone last word such as "niet" of "Verloopt niet" from sitting on a line of its own */
.dd-ca__lv{flex:1; min-height:0; display:flex; flex-direction:column; text-wrap:pretty;}
.dd-calist{list-style:none; margin:0; padding:0; display:grid; gap:var(--space-2);}
.dd-calist__it{display:flex; align-items:flex-start; gap:var(--space-3); padding:var(--space-2) var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-calist__bd{flex:1; min-width:0; display:flex; flex-direction:column; gap:var(--space-1);}
.dd-calist__n{font-size:13px; font-weight:700; color:var(--text-primary); overflow-wrap:anywhere;}
.dd-calist__d{display:flex; flex-direction:column; gap:var(--space-1);}
.dd-calist__ev{display:inline-flex; align-items:center; gap:var(--space-2); font-size:12px; font-weight:700; overflow-wrap:anywhere;}
.dd-calist__ev .shp{width:12px; height:12px; flex:0 0 12px;}
.dd-calist__m{font-size:11.5px; color:var(--text-muted); overflow-wrap:anywhere;}
.dd-calist__ro{display:inline-flex; align-items:center; gap:var(--space-1); font-size:11.5px; color:var(--text-secondary);}
.dd-calist__ro .ic{width:12px; height:12px; flex:0 0 12px; color:var(--text-muted);}
.dd-calist__it > .btn{flex:0 0 auto;}
.dd-calist__none{display:flex; align-items:flex-start; gap:var(--space-2); padding:var(--space-3); border:1px dashed var(--border-default); border-radius:var(--radius-md); font-size:12.5px; color:var(--text-secondary);}
.dd-calist__none .ic{width:16px; height:16px; flex:0 0 16px; color:var(--zone-control-stroke);}
.dd-calist__none p{margin:0;}
.dd-calist__none b{display:block; margin-bottom:var(--space-1); color:var(--text-primary);}

/* ------------------------------------------------------------ 16 first-use guide (R1-31; static/js/dd-guide.js) */
/* The welcome card is modal on a scrim; callouts sit beside their anchor, never over it, and the ring marks the anchor.
   Both live on body, above the page and the topbar, under the console's modals, context menu and toasts. The topbar's
   menus stack inside the topbar, so a callout and its ring step aside while one is open.
   Positions come from the CSSOM (left, top, max sizes, --dd-guide-caret); the state is in data-side and data-state. */
.dd-guide-scrim{position:fixed; inset:0; z-index:var(--z-modal); display:flex; align-items:center; justify-content:center; padding:var(--space-5); background:var(--surface-overlay);}
.dd-guide{background:var(--surface-0); color:var(--text-primary); border:1px solid var(--border-default); border-radius:var(--radius-lg); box-shadow:var(--elev-4); font-size:13px; line-height:1.45;}
.dd-guide:focus{outline:none;}
.dd-guide--card{width:min(560px, 100%); max-height:calc(100vh - 2 * var(--space-5)); display:flex; flex-direction:column; overflow:hidden;}
.dd-guide--callout{position:fixed; left:0; top:0; z-index:var(--z-modal); width:min(360px, calc(100vw - 2 * var(--space-2))); max-width:calc(100vw - 2 * var(--space-2)); display:flex; flex-direction:column; --dd-guide-caret:50%;}
.dd-guide__hd{display:flex; align-items:flex-start; gap:var(--space-3); padding:var(--space-4) var(--space-3) var(--space-2) var(--space-4);}
.dd-guide--card .dd-guide__hd{position:relative; padding-top:var(--space-5); border-bottom:1px solid var(--border-subtle);}
.dd-guide--card .dd-guide__hd::before{content:""; position:absolute; left:0; right:0; top:0; height:3px; background:var(--accent); border-radius:var(--radius-lg) var(--radius-lg) 0 0;}
.dd-guide__badge{width:36px; height:36px; flex:0 0 36px; border-radius:var(--radius-md); background:var(--accent-soft); color:var(--accent); display:flex; align-items:center; justify-content:center;}
.dd-guide__badge .ic{width:20px; height:20px;}
.dd-guide__hdtx{flex:1; min-width:0;}
.dd-guide__title{margin:0; font-size:15px; font-weight:800; line-height:1.3; color:var(--text-primary); overflow-wrap:anywhere;}
.dd-guide--card .dd-guide__title{font-size:17px;}
.dd-guide__sub{margin-top:2px; font-size:12px; color:var(--text-muted);}
.dd-guide__count{font:600 11px var(--font-mono); letter-spacing:.04em; color:var(--text-muted); margin-bottom:2px;}
.dd-guide__x{flex:0 0 auto; width:30px; height:30px; margin:-4px 0 0; border:0; border-radius:var(--radius-sm); background:none; color:var(--text-muted); display:flex; align-items:center; justify-content:center; cursor:pointer;}
.dd-guide__x:hover{background:var(--surface-2); color:var(--text-primary);}
.dd-guide__x .ic{width:16px; height:16px;}
.dd-guide__x:focus-visible{outline:2px solid var(--border-focus); outline-offset:1px;} /* [REMOVAL-186] .dd-setup__go dropped from this rule: a .btn, it shows the button's --focus-ring, which the outline doubled */
.dd-guide__bd{flex:1 1 auto; min-height:0; overflow:auto; padding:var(--space-2) var(--space-4) var(--space-3); color:var(--text-secondary); overflow-wrap:anywhere;}
.dd-guide--card .dd-guide__bd{padding-top:var(--space-4);}
.dd-guide__bd p{margin:0 0 var(--space-2);}
.dd-guide__bd p:last-child{margin-bottom:0;}
.dd-guide__list{list-style:none; margin:0 0 var(--space-3); padding:0; display:flex; flex-direction:column; gap:var(--space-2);}
.dd-guide__list li{display:flex; align-items:center; gap:var(--space-2); color:var(--text-primary);}
.dd-guide__list .ic{width:17px; height:17px; flex:0 0 17px; color:var(--accent);}
.dd-guide__list b{font-weight:700;}
.dd-guide__hint,.dd-guide__away{display:flex; align-items:flex-start; gap:var(--space-2); font-size:12px; color:var(--text-muted);}
.dd-guide__hint .ic,.dd-guide__away .ic{width:15px; height:15px; flex:0 0 15px; margin-top:1px;}
.dd-guide__away{margin-top:var(--space-2);}
.dd-guide__doc{display:flex; align-items:center; gap:var(--space-2); font-size:13px;}
.dd-guide__doc .ic{width:15px; height:15px; flex:0 0 15px; color:var(--accent);}
.dd-guide__doc a{color:var(--text-link); font-weight:600;}
.dd-guide__doc a:hover{color:var(--text-link-hover);}
.dd-user__doc{text-decoration:none;}
.dd-guide__ft{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:var(--space-2); padding:var(--space-3) var(--space-4); border-top:1px solid var(--border-subtle); background:var(--surface-1); border-radius:0 0 var(--radius-lg) var(--radius-lg);}
.dd-guide__nav{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-left:auto;}
.dd-guide__ft .btn .ic{width:14px; height:14px;}
.dd-guide__caret{position:absolute; width:12px; height:12px; background:var(--surface-0); border:1px solid var(--border-default); transform:rotate(45deg); pointer-events:none;}
.dd-guide[data-side="bottom"] .dd-guide__caret{top:-7px; left:calc(var(--dd-guide-caret) - 6px); border-right:0; border-bottom:0;}
.dd-guide[data-side="top"] .dd-guide__caret{bottom:-7px; left:calc(var(--dd-guide-caret) - 6px); border-left:0; border-top:0; background:var(--surface-1);}
.dd-guide[data-side="right"] .dd-guide__caret{left:-7px; top:calc(var(--dd-guide-caret) - 6px); border-top:0; border-right:0;}
.dd-guide[data-side="left"] .dd-guide__caret{right:-7px; top:calc(var(--dd-guide-caret) - 6px); border-bottom:0; border-left:0;}
.dd-guide-ring{position:fixed; left:0; top:0; z-index:var(--z-modal); pointer-events:none; border-radius:var(--radius-md); box-shadow:0 0 0 2px var(--border-focus), var(--focus-ring);}
/* setup checklist on the administrator's welcome card: state is an icon plus text (done / to do), never lime */
.dd-setup{margin:0 0 var(--space-3);}
.dd-setup__hd{display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:var(--space-1) var(--space-3); margin-bottom:var(--space-2);}
.dd-setup__title{margin:0; font-size:13px; font-weight:800; color:var(--text-primary);}
.dd-setup__n{font:600 11px var(--font-mono); letter-spacing:.04em; color:var(--text-muted);}
.dd-setup__list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--space-2);}
/* one row per task; the link wraps under the text when a long tab name (nl, de) leaves the text too little room */
.dd-setup__item{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2) var(--space-3); padding:var(--space-2) var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--surface-1);}
.dd-setup__mark{flex:0 0 64px; display:flex; flex-direction:column; align-items:center; gap:2px; font-size:10.5px; font-weight:700; text-align:center;}
.dd-setup__mark .ic{width:18px; height:18px;}
.dd-setup__item[data-state="done"] .dd-setup__mark{color:var(--status-ok-fg);}
.dd-setup__item[data-state="todo"] .dd-setup__mark{color:var(--text-muted);}
.dd-setup__tx{flex:1 1 220px; display:flex; flex-direction:column; gap:2px; min-width:0; overflow-wrap:break-word;}
.dd-setup__tx b{color:var(--text-primary); font-weight:700;}
.dd-setup__tx span{font-size:12px; color:var(--text-secondary);}
.dd-setup__go{flex:0 0 auto; margin-left:auto; max-width:100%; white-space:normal; overflow-wrap:break-word; text-align:left; line-height:1.25;}
.dd-setup__msg{display:flex; align-items:center; gap:var(--space-2); font-size:12px; color:var(--text-muted);}
.dd-setup__msg .ic{width:16px; height:16px; color:var(--status-error-fg);}
@media (max-width:520px){
  .dd-setup__mark{flex-basis:52px;}
  .dd-setup__tx{flex-basis:160px;}
}
@media (prefers-reduced-motion:no-preference){
  .dd-guide--card{animation:dd-guide-in var(--dur-slow) var(--ease);}
  .dd-guide--callout{animation:dd-guide-in var(--dur-base) var(--ease);}
  .dd-guide-ring{transition:left var(--dur-fast) var(--ease), top var(--dur-fast) var(--ease), width var(--dur-fast) var(--ease), height var(--dur-fast) var(--ease);}
}
@keyframes dd-guide-in{from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:none;}}

/* ------------------------------------------------------------ 17 3D view (R1-31 WP7; static/js/dd-map3d.js, dd-map3d-scene.js) */
/* A floating window over the live map: above its panels, the detail and the control-area panel, under the hover card
   (which follows a pointer into it), the context menu, the modals and the toasts. The map library draws the ground in
   .dd-w3d__map; the air (drones, height chips, drop-lines, trails, labels) lies over it in .dd-w3d__air, placed through
   the CSSOM every frame. Sizes and places come from the CSSOM too (left, top, width, height). */
:root[data-palette="airspace"]{--dd-z-win3d:calc(var(--z-dd-panel) + 5);}
/* the accent tone of the 3D focus rings (drones and the map): in light the pressed accent, which keeps 3:1 over the
   translucent height-limit volumes where --accent falls to 2.6:1; dark keeps the accent (= --border-focus) */
:root[data-palette="airspace"]{--dd-w3d-ring:var(--accent);}
:root[data-palette="airspace"][data-theme="light"]{--dd-w3d-ring:var(--accent-active);}
/* overflow clip, not hidden, here, on the body and on the air: a hidden box is a scroll container, and the browser
   scrolls one to reveal a focused drone past its edge, which shifts the drones off their places on the map */
.dd-live-view > .dd-w3d{position:absolute; z-index:var(--dd-z-win3d); min-width:0; overflow:clip;}
.dd-live-view > .dd-hover.dd-hover--w3d{z-index:calc(var(--dd-z-win3d) + 1);}
.dd-w3d.is-moving{user-select:none;}
.dd-w3d.is-moving .dd-w3d__hd{cursor:grabbing;}
.dd-w3d.is-max .dd-w3d__hd{cursor:default;}
.dd-w3d__hd{gap:6px; padding-right:6px;}
.dd-w3d.is-narrow .dd-w3d__hd{gap:var(--space-1);}
.dd-w3d__hd::before{margin-right:var(--space-2);}
.dd-w3d__ti .shp{width:12px; height:12px;}
.dd-w3d__ti .ic{width:15px; height:15px;}
.dd-w3d__title{min-width:0; margin:0 var(--space-1) 0 0; display:flex; align-items:baseline; gap:var(--space-2); overflow:hidden; white-space:nowrap; border-radius:4px;}
.dd-w3d__title:focus{outline:none;}
.dd-w3d__title:focus-visible{box-shadow:var(--focus-ring);}
.dd-w3d__kind{flex:0 0 auto; font-size:10.5px; font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--text-muted);}
.dd-w3d__tname{min-width:0; overflow:hidden; text-overflow:ellipsis;}
/* the serial number or kind gives way first, so a narrow window still shows the name */
.dd-w3d__tsub{flex:0 1000 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; font-size:11px; font-weight:600; color:var(--text-muted);}
.dd-w3d__state{flex:0 0 auto;}
.dd-w3d__hd .win__ctl.is-on{background:var(--accent-soft); color:var(--accent);}
.dd-w3d__hd .win__ctl.is-paused{color:var(--status-warn-fg);}
.dd-w3d__hd .win__ctl:disabled{opacity:.4; cursor:not-allowed;}
.dd-w3d__hd .win__ctl:focus-visible{outline:2px solid var(--border-focus); outline-offset:-2px;}
.dd-w3d__k{width:auto; min-width:30px; padding:0 6px; font-size:12px; font-weight:700;}
.dd-w3d__bd{position:relative; overflow:hidden; overflow:clip; min-height:0; background:var(--map-bg);}
/* the 3D map's drones and trails draw over buildings and translucent volumes, so they take the 3D severity inks; the
   window's header, notes and the 2D map keep the shared ones */
#dd-w3d .dd-w3d__bd{--sev-low-ink:var(--map3d-sev-low-ink); --sev-medium-ink:var(--map3d-sev-medium-ink);
  --sev-high-ink:var(--map3d-sev-high-ink); --sev-critical-ink:var(--map3d-sev-critical-ink);}
/* the map library's style sheet, loaded after this one, makes its container position:relative: this selector outranks it */
.dd-w3d__bd > .dd-w3d__map{position:absolute; inset:0;}
.dd-w3d__map canvas:focus{outline:none;}
/* [REMOVAL-191] The map's single-tone inset outline replaced by the two-tone ring below: under 3:1 over the tinted
   buildings of protected objects */
/* the map's focus ring: the two tones of --focus-ring inset along the body's edge, since the body clips an outer ring and
   a canvas paints over its own inset shadow; the --surface-0 band lies inside the accent, between it and the map */
.dd-w3d__bd:has(> .dd-w3d__map canvas:focus-visible)::after{content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  box-shadow:inset 0 0 0 2px var(--dd-w3d-ring), inset 0 0 0 4px var(--surface-0);}
/* a stacking context of its own: the per-frame z-index of a drone (up to about 10^6) orders the drones among themselves
   and never lifts one over the window's buttons, badge, notes or resize handles */
.dd-w3d__air{position:absolute; inset:0; overflow:hidden; overflow:clip; isolation:isolate; pointer-events:none;}
.dd-w3d__air .is-off{display:none;}
.dd-live-view.is-stale .dd-w3d__air{opacity:.45; filter:grayscale(.6);}
.dd-w3d__svg{position:absolute; inset:0; width:100%; height:100%; overflow:visible;}
.dd-w3d__labels,.dd-w3d__marks{position:absolute; inset:0;}
.dd-w3d__lbl,.dd-w3d__trk,.dd-w3d__pin{position:absolute; left:0; top:0;}
.dd-w3d__trk{width:30px; height:30px; margin:-15px 0 0 -15px; pointer-events:auto;}
.dd-w3d__trk .trk__glyph,.dd-w3d__trk .dd-trk__hdg{transition:none;}
/* a non-cooperative drone's dashed severity edge gets the 3D casing (below); before the focus rule, which replaces it */
.dd-w3d__trk .trk[data-coop="false"]{box-shadow:0 0 0 1.5px var(--surface-0), var(--track-shadow);}
/* the --surface-0 band fills the gap inside the accent ring, parting it from what the map draws behind the drone */
.dd-w3d__trk:focus-visible .trk{outline:2px solid var(--dd-w3d-ring); outline-offset:4px; box-shadow:0 0 0 4px var(--surface-0), var(--track-shadow);}
.dd-w3d__pin{pointer-events:auto;}
.dd-pilot-icon.dd-w3d__pin{width:26px; height:26px; margin:-13px 0 0 -13px;}
.dd-home-icon.dd-w3d__pin{width:22px; height:22px; margin:-11px 0 0 -11px; pointer-events:none;}
/* the height above the ground, true metres at any height scale; "height unknown" when the sensor gives none */
.dd-w3d__alt{position:absolute; left:calc(100% + 6px); top:50%; transform:translateY(-50%); padding:1px 6px; border-radius:4px; background:var(--map-label-bg);
  border:1px solid var(--border-subtle); color:var(--text-primary); font-size:10.5px; font-weight:600; white-space:nowrap; pointer-events:none;}
.dd-w3d__alt.is-unk{color:var(--text-muted); border-style:dashed;}
.dd-focus-on .dd-w3d__trk.is-bg:not(:hover):not(:focus-visible) .dd-w3d__alt{display:none;}
.dd-w3d__drop{stroke:var(--map3d-drop); stroke-width:1.4; stroke-dasharray:var(--map3d-drop-dash);}
.dd-w3d__shadow{fill:var(--map3d-shadow);}
.dd-w3d__curtain{fill:var(--map3d-curtain); stroke:none;}
/* the top of a height limit: no-fly zones and control areas; an open band (no highest altitude) has a dashed top */
.dd-w3d__vtop{fill:none; stroke-width:1.6; stroke-linejoin:round;}
.dd-w3d__vtop--nfz{stroke:var(--zone-nfz-stroke);}
.dd-w3d__vtop--control{stroke:var(--zone-control-stroke);}
.dd-w3d__vtop.is-open{stroke-dasharray:var(--map3d-open-top-dash);}
/* the 3D casing: a solid --surface-0 line 1.5 px wider on each side under every trail, drop line and top of a height
   limit, so each keeps 3:1 against its casing where its own colour falls short over the scene (protected buildings);
   a stroke, not a drop-shadow filter, which would re-rasterize the air layer every frame */
.dd-w3d__case{fill:none; stroke:var(--surface-0); stroke-width:5.2; stroke-linecap:round; stroke-linejoin:round;}
.dd-w3d__case--drop{stroke-width:4.4; stroke-linecap:butt;}
.dd-w3d__case--vtop{stroke-width:4.6;}
.dd-focus-on .dd-w3d__case:is(.is-bg,.is-alert){opacity:var(--dd-focus-fade-line);}
/* camera buttons, top right; the height-scale badge top left; notes and the loading state over the map */
.dd-w3d__nav{position:absolute; top:10px; right:10px; z-index:2; gap:var(--space-2);}
.dd-w3d__nav button{width:34px; height:34px;}
.dd-w3d__nav button .ic{width:16px; height:16px;}
.dd-w3d__nav button:focus-visible{outline:2px solid var(--border-focus); outline-offset:-2px;}
.dd-w3d__badge{position:absolute; top:10px; left:10px; z-index:2; padding:3px 9px; border-radius:var(--radius-pill); background:var(--status-warn-bg);
  border:1px solid var(--status-warn-bd); color:var(--status-warn-fg); font-size:11px; font-weight:700; box-shadow:var(--elev-1);}
.dd-w3d__notes{position:absolute; left:10px; right:58px; bottom:10px; z-index:2; display:flex; flex-direction:column; align-items:flex-start; gap:6px; pointer-events:none;}
.dd-w3d__note{margin:0; max-width:100%; display:flex; align-items:center; gap:var(--space-2); padding:6px var(--space-2) 6px 10px; border-radius:var(--radius-md); background:var(--surface-0);
  border:1px solid var(--border-default); box-shadow:var(--elev-2); font-size:12px; line-height:1.35; color:var(--text-secondary); pointer-events:auto;}
.dd-w3d__note .ic{width:15px; height:15px; flex:0 0 15px; color:var(--text-muted);}
.dd-w3d__load{position:absolute; inset:0; z-index:2; display:flex; align-items:center; justify-content:center; gap:10px;
  background:color-mix(in srgb,var(--surface-0) 55%,transparent); color:var(--text-secondary); font-size:13px; font-weight:600;}
.dd-w3d__ft{gap:var(--space-3); min-height:30px; padding:5px var(--space-3); font-size:11px;}
.dd-w3d__src{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.dd-w3d__attr{flex:0 1 auto; min-width:0; max-width:55%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.dd-w3d__attr a{color:inherit;} .dd-w3d__attr a:focus-visible{outline-offset:-2px;} /* inset: the attribution clips an outer ring to cut its text short */
/* where the target's name would be cut short (is-narrow), "3D view", the serial number or kind and the word "Live" (its
   lime dot stays) go to screen readers only; the title's tooltip keeps the whole text */
.dd-w3d__live,.dd-w3d.is-narrow .dd-w3d__kind,.dd-w3d.is-narrow .dd-w3d__tsub,.dd-w3d.is-narrow .dd-w3d__stw{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;}
/* resize handles along the edges and in the corners, over the map's buttons (later in the DOM); none while maximised */
.dd-w3d__rz{position:absolute; z-index:2;}
.dd-w3d__rz--n,.dd-w3d__rz--s{left:12px; right:12px; height:7px; cursor:ns-resize;}
.dd-w3d__rz--e,.dd-w3d__rz--w{top:12px; bottom:12px; width:7px; cursor:ew-resize;}
.dd-w3d__rz--n{top:0;} .dd-w3d__rz--s{bottom:0;} .dd-w3d__rz--e{right:0;} .dd-w3d__rz--w{left:0;}
.dd-w3d__rz--ne,.dd-w3d__rz--se,.dd-w3d__rz--sw,.dd-w3d__rz--nw{width:14px; height:14px;}
.dd-w3d__rz--ne{top:0; right:0; cursor:nesw-resize;} .dd-w3d__rz--sw{bottom:0; left:0; cursor:nesw-resize;}
.dd-w3d__rz--nw{top:0; left:0; cursor:nwse-resize;} .dd-w3d__rz--se{bottom:0; right:0; cursor:nwse-resize;}
.dd-w3d.is-max .dd-w3d__rz{display:none;}

/* dispatch by e-mail, SMS and WhatsApp (R1-24): the channel under a channel's name, the WhatsApp template contract,
   the channels of a contact, and the delivery state of each message (a status pill with its own icon, never colour
   alone, never lime, never a severity shape) */
/* the eight Administration tabs, compact like .dd-lp__tabs, so the bar fits at 1440 px beside the pinned rail in every
   language (G08) */
#dd-a-tabs .tab{padding-left:var(--space-3); padding-right:var(--space-3); font-size:13px;}
.dd-chan{display:flex; align-items:center; gap:var(--space-1); color:var(--text-secondary); font-size:11.5px;}
#dd-ch-table .dd-ch-last{width:28%;}
.dd-chan .ic{width:13px; height:13px; flex:0 0 13px;}
.dd-tplvars{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--space-1) var(--space-3); margin:0 0 var(--space-3); padding:0; list-style:none; font-size:12.5px;}
.dd-tplvars li{display:flex; align-items:baseline; gap:var(--space-2); min-width:0;}
.dd-tplvars code{flex:0 0 auto; color:var(--text-secondary); font-size:11.5px;}
.dd-tpltext{resize:vertical; font-size:12px; line-height:1.45; background:var(--surface-1);}
.dd-tplbar{display:flex; align-items:center; justify-content:space-between; gap:var(--space-2); margin-top:var(--space-2);}
.dd-chchips{display:inline-flex; flex-wrap:wrap; gap:var(--space-1);}
.pill.dd-chchip{gap:var(--space-1);}
.pill.dd-chchip .ic{width:11px; height:11px; flex:0 0 11px;}
.pill.dd-chchip[data-ready="false"]{border-style:dashed; color:var(--text-muted);}
.dd-ct__tags{flex-wrap:wrap;}
.dd-contact__bd .dd-chchips{display:flex; margin-top:var(--space-1); overflow:visible; white-space:normal;}
.dd-contact__bd .dd-chchips .pill{color:var(--text-secondary); font-size:10.5px; overflow:visible;}
.dd-contact__bd .dd-chchips .pill[data-ready="false"]{color:var(--text-muted);}
.status-pill.dd-dlv{gap:var(--space-1); font-size:10.5px; white-space:normal; text-align:left;}
/* a delivery state wraps between its words only; a long serial or link in a note gives way instead, so Sent dispatches
   keeps beside the contacts at 1440 px with the rail pinned (G08) */
#dd-dp-table .dd-cell-remark{overflow-wrap:anywhere;}
.status-pill.dd-dlv .ic{width:11px; height:11px; flex:0 0 11px;}
.dd-dlv-list{display:flex; flex-direction:column; gap:var(--space-1); margin:0; padding:0; list-style:none;}
.dd-dlv-list li{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1);}
.dd-dlv-list__who{flex:1 0 100%;}
.dd-dlv-plan{display:flex; flex-direction:column; gap:var(--space-2); margin:0 0 var(--space-2); padding:0; list-style:none;}
.dd-dlv-plan li{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-1) var(--space-2); font-size:12.5px;}
.dd-dlv-plan__chips{display:inline-flex; flex-wrap:wrap; align-items:center; gap:var(--space-1) var(--space-2);}
.dd-modal .form-control[aria-invalid="true"]{border-color:var(--status-error-fg);}
/* support access (R1-94c): a platform operator's read-only session in this organisation; amber, never lime */
.dd-support-banner{flex:none; display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-4); background:var(--status-warn-bg); border-bottom:1px solid var(--status-warn-bd); color:var(--status-warn-fg); font-size:13px; font-weight:600;}
.dd-support-banner .ic{width:15px; height:15px; flex:0 0 15px;}
.dd-sg{margin-top:var(--space-5);}
.dd-sg__hd{display:flex; align-items:baseline; gap:var(--space-3); margin:0 0 var(--space-2);}
.dd-sg__hd h2{margin:0; font-size:15px;}
.dd-sg__reason{max-width:42ch; overflow-wrap:anywhere;}
