:root{
  /* light Shiprocket theme */
  --bg0:#ffffff; --bg1:#f7f8fc; --bg2:#eef0f8;
  --panel:rgba(28,32,64,.035); --panel2:rgba(28,32,64,.06);
  --bd:rgba(28,32,64,.10); --bd2:rgba(28,32,64,.16);
  --tx:#1d2140; --tx2:#5b6180; --tx3:#8a90a8;
  --pii:#ef4444; --pay:#e08a0b; --order:#2f6bff; --beh:#7c5cf6; --mkt:#16a34a; --cred:#7a8194;
  --shield:#6b2fe0;
  --brand:#7a3dff; --brand2:#6a2be0;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{font-family:"Inter","Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;color:var(--tx);
  background:radial-gradient(1100px 520px at 12% -10%, #f0ebff 0%, transparent 55%),
    radial-gradient(900px 600px at 100% 0%, #e9f1ff 0%, transparent 50%),
    linear-gradient(180deg,#ffffff,#f7f8fc);
  background-attachment:fixed; overflow-x:hidden; color-scheme:light;
  display:flex; flex-direction:column; min-height:100dvh;}
a{color:var(--brand)}

/* header */
header{padding:14px 22px 12px; border-bottom:1px solid var(--bd); position:relative; z-index:5;
  background:linear-gradient(180deg,#ffffff,rgba(255,255,255,0));}
.title{font-size:22px; font-weight:800; margin:0;
  background:linear-gradient(90deg,#7a3dff,#9b4dff 50%,#6a2be0 90%);-webkit-background-clip:text;background-clip:text;color:transparent;}
/* tagline beside the brand — lighter + smaller, and opted OUT of the title's gradient text-fill */
.title-sub{font-weight:500; font-size:.6em; color:var(--tx2); -webkit-text-fill-color:var(--tx2); background:none; letter-spacing:0}
.sub{color:var(--tx2); font-size:13px; margin-top:3px; max-width:1000px}
.bar{display:flex; flex-wrap:wrap; gap:14px; align-items:center; margin-top:12px; justify-content:space-between}
/* F6: floating command-bar "island" — CSS only, buttons unchanged */
.controls{display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  background:rgba(255,255,255,.66); backdrop-filter:blur(14px) saturate(1.25); border:1px solid var(--bd2);
  border-radius:16px; padding:8px 10px; box-shadow:0 12px 30px -14px rgba(28,32,64,.4), inset 0 1px 0 rgba(255,255,255,.55)}
body.dark .controls{background:rgba(13,19,46,.5); border-color:rgba(255,255,255,.14);
  box-shadow:0 14px 36px -14px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.06)}
button.ctl{cursor:pointer; border:1px solid var(--bd2); background:#fff; color:var(--tx);
  padding:8px 13px; border-radius:9px; font-size:13px; font-weight:600; display:inline-flex; gap:7px; align-items:center; transition:.18s;
  box-shadow:0 1px 2px rgba(28,32,64,.06);}
button.ctl:hover{border-color:var(--brand); background:#f5f1ff}   /* no translateY: lifting the button moves its hit-area off the cursor at the bottom edge → hover flicker loop */
button.ctl.on{background:#efe9ff; border-color:var(--brand); color:var(--brand2); box-shadow:0 0 0 1px rgba(122,61,255,.3)}
button.ctl.play{background:linear-gradient(90deg,#7a3dff,#9b4dff); border-color:transparent; color:#fff}
button.ctl.play.on{background:linear-gradient(90deg,#7a3dff,#9b4dff); border-color:transparent; color:#fff; box-shadow:0 1px 2px rgba(28,32,64,.06)}
button.ctl.pdf{background:linear-gradient(90deg,#16a34a,#0ea371); border-color:transparent; color:#fff}
button.ctl:disabled{opacity:.5; cursor:default; transform:none}
button.ctl:focus{outline:none}                       /* no lingering ring after a click (Play/Stop) */
button.ctl:focus-visible{outline:2px solid var(--brand); outline-offset:2px}   /* keep it for keyboard nav */
/* tabs: Standard flow (read-only) / Check my data flow (build-your-own) */
.dl-tabs{display:flex; gap:8px; margin-top:14px; width:100%}
.dl-tab{flex:1 1 0; display:flex; flex-direction:column; align-items:center; gap:2px; text-align:center; cursor:pointer;
  border:1px solid var(--bd2); background:var(--panel); color:var(--tx2);
  padding:10px 8px; border-radius:12px; transition:.18s}
.dl-tab-t{font-size:15px; font-weight:700}
.dl-tab-d{font-size:11.5px; font-weight:500; color:var(--tx3); letter-spacing:.01em}
.dl-tab:hover{color:var(--tx); border-color:var(--brand)}
.dl-tab.active{background:var(--brand); color:#fff; border-color:transparent; box-shadow:0 4px 14px rgba(124,58,237,.45)}
.dl-tab.active .dl-tab-d{color:rgba(255,255,255,.78)}
body.dark .dl-tab.active{background:linear-gradient(90deg,#7c3aed,#2563eb)}
/* Anti-flash: hide the WHOLE app until boot() has set the right classes + done the first render (adds
   body.dl-ready). Before that, the raw markup would flash the desktop layout (form panel, drawer) on load.
   A safety timeout in the inline boot script also adds dl-ready, so the app can never get stuck hidden. */
body:not(.dl-ready) .datalens-app{visibility:hidden}
/* read-only tabs (Standard, Sample): no form, no rail arrow, no reset */
body.readonly .form-panel, body.readonly .rail-arrow{display:none !important}
/* names-only tab (Standard): hide the values — PII badges + arrow labels (flow still animates) */
body.names-only .badge, body.names-only .elabel{display:none !important}
.legend{display:flex; flex-wrap:wrap; gap:6px 14px; align-items:center}
.lg{display:inline-flex; gap:6px; align-items:center; font-size:11.5px; color:var(--tx2)}
.dot{width:10px; height:10px; border-radius:50%}

/* layout: form | stage | drawer */
.main{display:flex; align-items:stretch; flex:1 1 auto; min-height:0; overflow:hidden; position:relative}
/* LEFT options: overlay rail, collapsed to a tab, slides out on hover */
.form-panel{position:absolute; left:0; top:0; bottom:0; width:264px; z-index:25;
  border-right:1px solid var(--bd2); padding:14px 14px 30px; overflow-y:auto;
  background:rgba(255,255,255,.85); backdrop-filter:blur(20px) saturate(1.1);
  box-shadow:2px 0 16px rgba(28,32,64,.05);
  transform:translateX(0); transition:transform .22s ease}
/* visible by default; once a flow exists it tucks fully away, reopened via the arrow */
body.has-flow .form-panel{transform:translateX(-100%)}
body.has-flow .form-panel.open, body.has-flow .form-panel.pin{transform:translateX(0); box-shadow:10px 0 34px rgba(28,32,64,.18)}
/* floating arrow handle — only shown once a flow exists */
.rail-arrow{position:absolute; left:10px; top:50%; transform:translateY(-50%); width:30px; height:62px; z-index:20;
  display:none; align-items:center; justify-content:center; border:0; padding:0; cursor:pointer; user-select:none;
  border-radius:0 16px 16px 0; color:#fff; font-size:0; outline:none;
  background:linear-gradient(135deg,#7a3dff,#9b4dff);
  box-shadow:0 6px 20px -4px rgba(122,61,255,.55);
  transition:transform .2s ease, box-shadow .2s ease, background .2s ease;
  animation:railpulse 2.4s ease-in-out infinite}
body.has-flow .rail-arrow{display:flex}
.rail-arrow span{font-size:20px; font-weight:800; line-height:1; color:#fff; transition:transform .2s ease}
.rail-arrow::before{content:""; position:absolute; left:0; top:50%; transform:translateY(-50%); width:3px; height:30px; border-radius:3px;
  background:rgba(255,255,255,.85)}
.rail-arrow:hover{transform:translateY(-50%) translateX(2px);
  box-shadow:0 10px 28px -4px rgba(122,61,255,.75)}
.rail-arrow:hover span{transform:translateX(2px)}
@keyframes railpulse{0%,100%{box-shadow:0 6px 20px -6px rgba(122,61,255,.45)}
  50%{box-shadow:0 8px 26px -4px rgba(122,61,255,.7)}}
.form-panel.pin ~ .rail-arrow{opacity:0; pointer-events:none}
body.focus .form-panel, body.focus .rail-arrow{display:none}
/* Standard tab: toolbar + pinned popup are diagram tools — reveal only while the diagram is on screen.
   JS toggles .diag-hidden (IntersectionObserver on the diagram) when you scroll into the reading sections. */
.bar{max-height:420px; transition:opacity .2s ease, max-height .28s ease}
body.tab-standard.diag-hidden .bar{opacity:0; max-height:0; margin-top:0; overflow:hidden; pointer-events:none}
body.tab-standard.diag-hidden .drawer{display:none}
.fp-h{font-size:12px; font-weight:800; letter-spacing:1px; text-transform:uppercase; color:var(--tx3); margin:0 0 10px}
.fld{display:block; margin-bottom:11px}
.flab{display:block; font-size:11.5px; color:var(--tx2); margin-bottom:4px; font-weight:600}
.fhint{font-size:10px; color:var(--tx3); margin-top:4px; line-height:1.35}
.req{color:#e11d48; font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px}
.opt{color:var(--tx3); font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px}
.grp{color:#b45309; font-size:9.5px; font-weight:700; text-transform:uppercase; letter-spacing:.5px}
.cust{width:100%; margin-top:5px; padding:6px 9px; border-radius:8px; border:1px dashed var(--bd2); background:rgba(28,32,64,.02); color:var(--tx); font-size:12px}
.cust::placeholder{color:var(--tx3); font-style:italic}
.mchk.single{margin-top:2px}
.fld select,.fld input[type=text],.fld input.combo{width:100%; padding:7px 9px; border-radius:8px; border:1px solid var(--bd2);
  background:#fff; color:var(--tx); font-size:12.5px; color-scheme:light}
.fld input::placeholder{color:var(--tx3)}
.fld input.combo:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(122,61,255,.15)}
/* custom combobox popup */
.combo-wrap{position:relative}
.combo-caret{position:absolute; right:9px; top:8px; font-size:11px; color:var(--tx3); pointer-events:none}
.combo-pop{position:absolute; left:0; right:0; top:calc(100% + 4px); z-index:40; max-height:230px; overflow-y:auto; display:none;
  background:#fff; border:1px solid var(--bd2); border-radius:11px;
  box-shadow:0 16px 38px rgba(28,32,64,.16); padding:4px}
.combo-pop.open{display:block}
.combo-opt{padding:7px 10px; cursor:pointer; border-radius:8px; display:flex; flex-direction:column; gap:1px; transition:background .12s}
.combo-opt:hover{background:#f3eeff}
.combo-opt b{font-size:12.5px; color:var(--tx); font-weight:600}
.combo-opt span{font-size:10px; color:var(--tx3); letter-spacing:.2px}
.combo-opt.custom{color:var(--tx2); font-size:11.5px}
.combo-opt.custom b{color:var(--brand)}
.combo-empty{padding:8px 10px; font-size:11px; color:var(--tx3); font-style:italic}
/* selected courier chips */
.chips-box{display:flex; flex-wrap:wrap; gap:4px; margin-bottom:5px}
.chips-box:empty{display:none}
.chip-sel{display:inline-flex; align-items:center; gap:5px; font-size:11px; padding:3px 8px; border-radius:14px;
  background:rgba(122,61,255,.10); border:1px solid rgba(122,61,255,.35); color:var(--brand2)}
.chip-sel .x{cursor:pointer; font-style:normal; color:var(--tx2); font-weight:800; line-height:1; font-size:13px}
.chip-sel .x:hover{color:var(--pii)}
.combo-pop::-webkit-scrollbar{width:8px}
.combo-pop::-webkit-scrollbar-thumb{background:rgba(28,32,64,.16); border-radius:8px}
.multi{display:flex; flex-direction:column; gap:4px; border:1px solid var(--bd); border-radius:8px; padding:7px 9px; background:#fff}
.mchk{font-size:12px; color:var(--tx); display:flex; gap:7px; align-items:center; cursor:pointer}
.fp-actions{display:flex; flex-direction:column; gap:8px; margin-top:14px}
.fp-actions button{width:100%; justify-content:center}

.stage-area{flex:1; min-width:0; position:relative; padding:10px 4px 10px 12px; overflow:hidden; width:100%}
.stage-wrap{position:relative; width:100%; height:100%; overflow:hidden; cursor:grab}
.stage-wrap.grabbing{cursor:grabbing}
.stage{position:absolute; top:0; left:0; width:1440px; height:860px; transform-origin:0 0}
svg.wires{position:absolute; inset:0; width:1440px; height:860px; overflow:visible}
.edge-base{fill:none; stroke:rgba(28,32,64,.14); stroke-width:2}
.edge-flow{fill:none; stroke-width:2.6; stroke-dasharray:9 9; stroke-linecap:round; animation:march 1.1s linear infinite; opacity:.95; filter:drop-shadow(0 0 1.5px var(--c))}
.edge-flow.ret{stroke-dasharray:3 11; opacity:.7; animation-duration:1.8s}
@keyframes march{ to{ stroke-dashoffset:-36 } }
.edge-hit{fill:none; stroke:transparent; stroke-width:22; cursor:pointer; pointer-events:stroke}
.g-edge.focus .edge-flow{stroke-width:3.6; opacity:1; filter:drop-shadow(0 0 5px var(--c))}
.g-edge.focus .edge-base{stroke:rgba(28,32,64,.3)}
.packet{filter:drop-shadow(0 0 4px var(--c)); pointer-events:none}

.node{position:absolute; width:168px; min-height:74px; transform:translate(-50%,-50%) translateZ(0);
  background:#ffffff; border:1px solid var(--bd);
  border-radius:14px; padding:10px 12px; display:flex; gap:10px; align-items:center; cursor:pointer;
  box-shadow:0 6px 18px rgba(28,32,64,.10); transition:transform .16s,border-color .16s,box-shadow .16s; z-index:2;
  /* rasterize at the composited (zoomed) resolution, not a cheap 1x texture. translateZ(0)/backface
     promote a layer WITHOUT will-change (which would pin a low-res texture and keep text soft). */
  backface-visibility:hidden}
.node-tx{min-width:0}
.node:hover{transform:translate(-50%,-50%) scale(1.045); border-color:var(--accent); box-shadow:0 0 0 1px var(--accent), 0 12px 26px -6px color-mix(in srgb,var(--accent) 45%, transparent)}
/* focus (hover/pin) = highlight AND a little "pop" so the connected boxes lift out of the map */
.node.focus{transform:translate(-50%,-50%) scale(1.16); border-color:var(--accent); box-shadow:0 0 0 1px var(--accent), 0 20px 42px -10px color-mix(in srgb,var(--accent) 62%, transparent); z-index:5}
.node.pinned{transform:translate(-50%,-50%) scale(1.2); outline:2px dashed var(--accent); outline-offset:3px; z-index:6}
.node-ic{width:42px; height:42px; flex:0 0 42px; border-radius:11px; display:grid; place-items:center; font-size:21px;
  background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 22%, #fff), #fff);
  border:1px solid color-mix(in srgb,var(--accent) 35%, #fff)}
/* brand logos */
.node-ic.has-logo, .di.has-logo{background:#fff; border-color:var(--bd); padding:4px}
.node-logo{width:100%; height:100%; object-fit:contain; display:block}
.di .node-logo{width:100%; height:100%}
/* explicit emoji font: the PDF clone (SVG foreignObject) doesn't inherit the body's emoji fallback, so the
   category emoji (browser/last-mile/other) printed blank while <img> brand logos printed fine. */
.ic-fb{display:none; font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","Twemoji Mozilla",sans-serif; line-height:1}
.ic-fb.only{display:block}
.node-ic.emoji, .di.emoji{background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 22%, #fff), #fff); padding:0}
.node-ic.emoji .ic-fb, .di.emoji .ic-fb{display:grid; place-items:center; width:100%; height:100%}
/* multi-courier node: a card listing each courier with its logo + name */
.node.multi-node{width:196px; height:auto; align-items:flex-start; flex-direction:column; gap:6px; padding:10px 12px}
.node-tx.full{width:100%}
.cgrid{display:flex; flex-wrap:wrap; gap:4px; margin-top:6px}
.cchip{display:inline-flex; align-items:center; gap:5px; font-size:10.5px; color:var(--tx);
  background:#f6f7fb; border:1px solid var(--bd); border-radius:9px; padding:2px 7px 2px 3px}
.cchip img{width:16px; height:16px; object-fit:contain; background:#fff; border-radius:4px; padding:1px}
.cchip .cdot{width:16px; height:16px; display:grid; place-items:center; font-size:11px}
.cchip .cnm{font-weight:600}
.node-nm{font-size:13px; font-weight:700; line-height:1.12; white-space:normal; overflow-wrap:anywhere}
.node-sub{font-size:10px; color:var(--tx3); margin-top:2px; white-space:normal; overflow-wrap:anywhere}
.node .badge{position:absolute; top:-9px; right:-9px; background:var(--pii); color:#fff; font-size:9.5px; font-weight:800;
  border-radius:20px; padding:2px 7px; box-shadow:0 2px 6px rgba(239,68,68,.4); display:none}
.node[data-pii="1"] .badge{display:block}
/* per-node risk dot (top-left corner) — coloured by data sensitivity, see riskOf() */
.node .risk-dot{position:absolute; top:-5px; left:-5px; width:11px; height:11px; border-radius:50%;
  border:2px solid #fff; box-shadow:0 1px 3px rgba(28,32,64,.35); background:#5b9e7d; z-index:4}
.node[data-risk="high"] .risk-dot{background:#FF5A6E}
.node[data-risk="med"]  .risk-dot{background:#FFB020}
.node[data-risk="low"]  .risk-dot{background:#5b9e7d}
body.dark .node .risk-dot{border-color:#0b1020; box-shadow:0 0 6px rgba(0,0,0,.55)}
/* F1: data-class dots — one per distinct class the box holds (legend colours) */
.ndots{display:flex; gap:3px; margin-top:5px}
.ndot{width:7px; height:7px; border-radius:50%; background:var(--cc); box-shadow:0 0 5px -1px var(--cc)}
/* F3: full asset card — labelled data list inside the node (rows clamped to 1 line so height stays bounded) */
.ncard{display:flex; flex-direction:column; gap:2px; margin-top:6px}
.ncard-row{display:flex; align-items:center; gap:5px; font-size:9.5px; color:var(--tx2); line-height:1.25;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%}
.ncard-row i{flex:0 0 6px; width:6px; height:6px; border-radius:50%; background:var(--cc); box-shadow:0 0 4px -1px var(--cc)}
.ncard-more{font-size:9px; color:var(--tx3); font-weight:600; margin-top:1px}
/* F2: PII heatmap — in Highlight-PII mode, high-risk boxes glow red, medium amber */
body.pii-heat .node[data-risk="high"]{box-shadow:0 0 0 1px #ff5a6e, 0 0 26px -2px #ff5a6e}
body.pii-heat .node[data-risk="med"]{box-shadow:0 0 0 1px #ffb020, 0 0 16px -4px #ffb020}
/* F4: guided builder — group fields into cards */
.fgroup{border:1px solid var(--bd); border-radius:12px; padding:11px 12px 4px; margin-bottom:12px; background:var(--panel)}
.fgroup .fld:last-child{margin-bottom:7px}
.fg-h{font-size:10.5px; font-weight:800; letter-spacing:.8px; text-transform:uppercase; color:var(--tx3);
  margin:0 0 9px; display:flex; align-items:center; gap:7px}
.fg-h::after{content:""; flex:1; height:1px; background:var(--bd)}
body.dark .fgroup{background:rgba(255,255,255,.03)}

.elabel{position:absolute; transform:translate(-50%,-50%); font-size:10.5px; font-weight:600; color:var(--tx);
  background:#fff; border:1px solid var(--bd2); border-radius:7px; padding:3px 7px; white-space:nowrap; pointer-events:none; z-index:3; box-shadow:0 4px 14px rgba(28,32,64,.16);
  opacity:0; transition:opacity .14s}              /* hidden until its node/edge is hovered */
.elabel.focus{opacity:1; z-index:7}                /* shown on hover — sits above the boxes */
.elabel .lc{display:inline-block; width:7px; height:7px; border-radius:50%; margin-right:5px; vertical-align:middle}

.stage.soft .node:not(.focus){opacity:.28; filter:saturate(.6)}
.stage.soft .g-edge:not(.focus){opacity:.14}
.stage.soft .elabel:not(.focus){opacity:0}

.caption{position:absolute; left:50%; bottom:14px; transform:translateX(-50%); max-width:760px; width:calc(100% - 60px);
  background:linear-gradient(90deg,#7a3dff,#9b4dff); border:1px solid rgba(255,255,255,.25);
  color:#fff; padding:11px 16px; border-radius:12px; font-size:13.5px; display:none; z-index:6; box-shadow:0 12px 30px rgba(122,61,255,.3)}
.caption b{color:#ffe9a8}
.caption .step{font-size:10.5px; opacity:.85; letter-spacing:1px; text-transform:uppercase; display:block; margin-bottom:2px}

.empty-state{display:grid; place-items:center; height:60vh; text-align:center; color:var(--tx3)}
.empty-state>div{max-width:430px}
.empty-state .es-ic{font-size:40px; margin:0 auto 14px; width:84px; height:84px; display:grid; place-items:center;
  border-radius:50%; background:color-mix(in srgb,var(--brand) 12%, transparent); border:1px solid color-mix(in srgb,var(--brand) 35%, transparent)}
.empty-state h3{color:var(--tx); margin:0 0 6px; font-weight:800}

/* drawer */
/* RIGHT details: overlay, slides in only when a block is hovered/clicked */
.drawer{position:absolute; right:0; top:0; bottom:0; width:350px; z-index:25;
  border-left:1px solid var(--bd2); padding:16px 16px 30px; overflow-y:auto;
  background:rgba(255,255,255,.88); backdrop-filter:blur(20px) saturate(1.1);
  transform:translateX(100%); transition:transform .22s ease}
.drawer.open{transform:translateX(0); box-shadow:-12px 0 36px rgba(28,32,64,.14), inset 1px 0 0 rgba(122,61,255,.25)}
.dh{display:flex; gap:12px; align-items:center; margin-bottom:6px}
.dh .di{width:46px;height:46px;flex:0 0 46px;border-radius:12px;display:grid;place-items:center;font-size:23px;
  background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 22%, #fff), #fff); border:1px solid color-mix(in srgb,var(--accent) 35%, #fff)}
.dh h2{font-size:17px; margin:0; font-weight:800}
.dh .dt{font-size:11px; color:var(--tx3); margin-top:2px}
.pin-hint{font-size:10.5px; color:var(--tx3); margin:2px 0 12px}
.role{font-size:13px; color:var(--tx2); line-height:1.5; margin:0 0 14px; padding:10px 12px; background:var(--panel); border:1px solid var(--bd); border-left:3px solid var(--accent); border-radius:9px}
.sec-t{font-size:11px; font-weight:800; letter-spacing:1.2px; text-transform:uppercase; color:var(--tx3); margin:16px 0 8px; display:flex; align-items:center; gap:7px}
.sec-t::after{content:""; flex:1; height:1px; background:var(--bd)}
.chips{display:flex; flex-wrap:wrap; gap:6px}
.chip{font-size:11.5px; padding:4px 9px; border-radius:20px; border:1px solid color-mix(in srgb,var(--cc,#888) 35%, #fff); color:var(--tx); background:color-mix(in srgb,var(--cc,#888) 12%, #fff); display:inline-flex; gap:6px; align-items:center}
.chip i{width:7px;height:7px;border-radius:50%;background:var(--cc,#888)}
.shares{list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:7px}
.shares li{font-size:12.5px; background:var(--panel); border:1px solid var(--bd); border-radius:9px; padding:8px 10px}
.shares li .to{font-weight:700; color:var(--tx); display:flex; align-items:center; gap:6px}
.shares li .wh{color:var(--tx2); font-size:12px; margin-top:2px}
.guards{list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:6px}
.guards li{font-size:12.5px; line-height:1.4; padding:8px 10px 8px 32px; position:relative; background:linear-gradient(90deg,rgba(122,61,255,.07),transparent); border:1px solid rgba(122,61,255,.18); border-radius:9px; color:var(--tx)}
.guards li::before{content:"\1F6E1"; position:absolute; left:9px; top:7px; font-size:13px}
.risk{margin-top:10px; font-size:12px; padding:9px 11px; border-radius:9px; color:#b91c1c; background:#fef2f2; border:1px solid #fecaca}
.risk b{color:#991b1b}
.intro p{font-size:12.5px; color:var(--tx2); line-height:1.55}
.drawer::-webkit-scrollbar{width:9px}
.drawer::-webkit-scrollbar-thumb{background:rgba(28,32,64,.16); border-radius:9px}

footer{padding:12px 22px; border-top:1px solid rgba(245,166,35,.4); color:var(--tx); font-size:13px; line-height:1.45; font-weight:500; text-align:center; background:rgba(245,166,35,.12)}
.dl-copyright{font-size:12px; font-weight:600; opacity:.75; letter-spacing:.02em}

/* ---- printable report (hidden on screen, shown only when printing) ---- */
.report{display:none; color:#1a1f2e; background:#fff; padding:28px 34px; font-size:12px; line-height:1.5}
.report h1{font-size:21px; margin:0 0 2px; color:#0f172a}
.report h2{font-size:15px; margin:22px 0 8px; color:#0f172a; border-bottom:2px solid #e2e8f0; padding-bottom:4px}
.report h3{font-size:13.5px; margin:0 0 6px; color:#0f172a; display:flex; align-items:center; gap:8px}
.r-head{border-bottom:3px solid #7a3dff; padding-bottom:10px; margin-bottom:14px}
.r-seller{font-size:13px; color:#0f172a; margin-top:4px}
.r-seller b{color:#5a2bd0}
.r-meta{font-size:11px; color:#64748b; margin-top:3px}
/* compliance report header — metric cards + risk profile (print-friendly) */
.r-metrics{display:flex; flex-wrap:wrap; gap:10px; margin-top:11px}
.r-metric{flex:1 1 130px; border:1px solid #e2e8f0; border-radius:9px; padding:8px 11px; background:#f8fafc}
.r-metric .rm-n{display:block; font-size:20px; font-weight:800; color:#0f172a; line-height:1.1}
.r-metric .rm-l{display:block; font-size:10px; font-weight:700; letter-spacing:.4px; text-transform:uppercase; color:#64748b; margin-top:2px}
.r-riskprofile{margin-top:10px; font-size:12px; font-weight:600; color:#334155}
.r-riskprofile .rk-hi{color:#c2334a} .r-riskprofile .rk-md{color:#9a6a10} .r-riskprofile .rk-lo{color:#3f7a5f}
.r-sub{font-size:10px; font-weight:800; letter-spacing:.6px; text-transform:uppercase; color:#64748b; margin:12px 0 5px}
.r-sysub{font-size:10.5px; font-weight:500; color:#94a3b8; margin-left:auto}
.r-pills{display:flex; flex-wrap:wrap; gap:5px; margin-bottom:8px}
.r-pill{font-size:10.5px; background:#f1ecff; border:1px solid #d6c8ff; color:#5a2bd0; border-radius:20px; padding:2px 9px}
.r-legend{display:flex; flex-wrap:wrap; gap:5px 12px; margin:6px 0 4px}
.r-chip{font-size:10px; color:#334155; display:inline-flex; gap:5px; align-items:center}
.r-chip i,.r-tag::before{width:8px; height:8px; border-radius:50%; background:var(--cc,#888); display:inline-block}
.r-tag{font-size:10px; display:inline-flex; gap:5px; align-items:center; color:#334155}
.r-tag::before{content:""}
.r-pii{color:#e11d48; font-weight:800; font-size:9.5px; background:#ffe4e6; border:1px solid #fecdd3; border-radius:5px; padding:1px 5px}
.r-diagram{margin:12px 0; border:1px solid #e2e8f0; border-radius:10px; overflow:hidden}
.r-diagram img{width:100%; display:block}
.r-note{font-size:11px; color:#475569; margin:4px 0 8px}
.r-disclaimer{margin-top:24px; padding:12px 14px; border:1px solid #e2b25a; background:#fdf6e6; border-radius:8px; font-size:11px; line-height:1.55; color:#6b4e12}
.r-table{width:100%; border-collapse:collapse; margin:4px 0 8px}
.r-table th{font-size:9.5px; text-transform:uppercase; letter-spacing:.5px; color:#64748b; text-align:left; border-bottom:1.5px solid #cbd5e1; padding:5px 8px}
.r-table td{font-size:11px; padding:5px 8px; border-bottom:1px solid #eef1f6; vertical-align:top}
.r-sys{border:1px solid #e2e8f0; border-radius:10px; padding:11px 13px; margin:10px 0; break-inside:avoid; page-break-inside:avoid}
.r-shares{margin:2px 0 6px; padding-left:16px}
.r-shares li{font-size:11px; margin:2px 0}
.r-guards{margin:2px 0 2px; padding-left:2px; columns:1; list-style:none}   /* single column, stacked rows (was 2-up) */
.r-guards li{font-size:10.5px; margin:3px 0 5px; break-inside:avoid; position:relative; padding-left:15px}
.r-guards li::before{content:"•"; position:absolute; left:2px; top:0; color:#7a3dff; font-weight:700}   /* bullet so each recommendation row is distinguishable in the single column */
.r-risk{font-size:11px; color:#9f1239; background:#fff1f2; border:1px solid #fecdd3; border-radius:7px; padding:7px 9px; margin:6px 0}

/* ---------- touch + responsive (scales down to phones) ---------- */
.stage-wrap{touch-action:none}                 /* canvas owns pan/pinch; page doesn't scroll over it */
/* dim backdrop behind the options drawer on phones — tap to close */
.panel-backdrop{position:absolute; inset:0; z-index:24; background:rgba(4,7,20,.45); opacity:0; pointer-events:none; transition:opacity .2s ease}
body.panel-open .panel-backdrop{opacity:1; pointer-events:auto}
/* floating close button — only shown on phones, where the drawer is a full bottom sheet */
.drawer-x{position:fixed; z-index:60; display:none; width:36px; height:36px; border-radius:50%; padding:0;
  align-items:center; justify-content:center; cursor:pointer; font-size:15px; line-height:1;
  border:1px solid var(--bd2); background:#fff; color:var(--tx); box-shadow:0 3px 10px rgba(28,32,64,.22)}
body.dark .drawer-x{background:rgba(13,19,46,.95); border-color:rgba(255,255,255,.2); color:#eaf3ff}
body.is-phone.drawer-open .drawer-x{display:flex; right:14px; top:14px; bottom:auto}

@media (max-width:900px){
  .title{font-size:23px}
  .sub{font-size:12px}
  .bar{gap:10px; margin-top:10px}
  .controls{position:relative; flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; padding:6px 0 8px; scrollbar-width:thin}  /* top pad so the highlighted button's glow isn't clipped by overflow */
  .controls::-webkit-scrollbar{height:4px}
  .controls::-webkit-scrollbar-thumb{background:var(--bd2); border-radius:4px}
  /* right-edge fade hints there are more buttons to scroll to */
  .controls::after{content:""; position:sticky; right:0; flex:0 0 30px; align-self:stretch; margin-left:-30px; pointer-events:none;
    background:linear-gradient(to right, rgba(255,255,255,0), #f7f8fc)}
  body.dark .controls::after{background:linear-gradient(to right, rgba(7,11,30,0), #070b1e)}
  .ctl{flex:0 0 auto; height:38px}   /* uniform height so Play/Stop align with the rest of the row */
  .form-panel{width:min(290px,86vw)}
  .drawer{width:min(370px,94vw)}
}

/* ============================================================
   PHONE LAYOUT — keyed on body.is-phone (set by JS from viewport SHORT-side + touch),
   so it applies in BOTH portrait and landscape. A rotated phone is no longer mistaken
   for desktop. Width-only @media(max-width:560px) blocks above still cover portrait;
   these class rules extend the same look to landscape and add the 2.0 chrome.
   ============================================================ */
body.is-phone header{padding:10px 12px 0; padding-top:max(10px, env(safe-area-inset-top))}
body.is-phone .title{font-size:18px}
body.is-phone .title-sub{display:none}            /* drop the tagline — reclaim the top row */
body.is-phone .sub{display:none}
body.is-phone .gen-stamp{display:none}
body.is-phone .bar{margin-top:8px; gap:8px}
body.is-phone .ctl{font-size:12px; padding:8px 11px}        /* taller = easier to tap */
body.is-phone .legend{font-size:10px; gap:9px; row-gap:5px}
body.is-phone .form-panel{width:min(310px,92vw)}
body.is-phone .dl-tabs{margin-top:10px}
/* drawer = bottom sheet fixed to the viewport (the ✕ is position:fixed, lands on its corner) */
body.is-phone .drawer{position:fixed; z-index:50; top:0; left:0; right:0; bottom:0; width:auto; height:100dvh; max-height:100dvh;
  border-left:0; border-top:0; border-radius:0; transform:translateY(100%)}
body.is-phone .drawer.open{transform:translateY(0); box-shadow:0 -14px 40px rgba(0,0,0,.32)}
body.is-phone .fp-h{font-size:13px}
body.is-phone .form-panel label{font-size:12px}
/* footer is chrome we don't need on a phone — the copyright still lives in the guide + PDF */
body.is-phone footer{display:none}

/* ---- 2.0 phone bottom action bar + "More" sheet ----
   Buttons are proxies (data-proxy) that click the real toolbar controls; state is reflected
   purely from body classes (playing / pii-heat / focus / dark) so there's nothing to keep in sync. */
.mobile-bar, .mobile-sheet, .mobile-sheet-backdrop{display:none}
body.is-phone .bar{display:none}                                   /* top toolbar replaced by the bottom bar */
body.is-phone .stage-area{padding-bottom:calc(60px + env(safe-area-inset-bottom))}   /* keep the diagram clear of the bar */

body.is-phone .mobile-bar{display:flex; position:fixed; left:0; right:0; bottom:0; z-index:55; gap:2px;
  padding:6px 6px calc(6px + env(safe-area-inset-bottom)); background:var(--bg1); border-top:1px solid var(--bd);
  box-shadow:0 -8px 24px rgba(0,0,0,.18)}          /* --bg1 is OPAQUE in both themes (--panel is a translucent tint → see-through) */
body.dark.is-phone .mobile-bar{background:#0b1122; border-top-color:rgba(255,255,255,.08)}
.m-btn{flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  height:52px; border:0; background:transparent; color:var(--tx2); cursor:pointer; border-radius:14px;
  font-weight:600; -webkit-tap-highlight-color:transparent;
  transition:background .18s ease, color .18s ease}
/* macOS-Dock-style life: on TAP the icon pops up + magnifies then springs back — a self-contained
   keyframe (not :active, which on touch only shows while the finger is held → invisible on a quick tap). */
.m-btn .m-ic{font-size:19px; line-height:1}
@keyframes m-pop{ 0%{transform:translateY(0) scale(1)} 32%{transform:translateY(-7px) scale(1.32)} 100%{transform:translateY(0) scale(1)} }
.m-btn.tapped .m-ic{animation:m-pop .36s cubic-bezier(.34,1.56,.64,1)}
.m-btn:active{background:color-mix(in srgb,var(--accent) 16%, transparent)}
/* the currently-active action stays lit with a clear pill + accent (Play=on, Personal=on, Full=on, More=open) */
body.playing .m-play, body.pii-heat .m-pii, body.focus .m-full, .m-more[aria-expanded="true"]{
  background:color-mix(in srgb,var(--accent) 22%, transparent); color:var(--accent)}
body.playing .m-play .m-ic, body.pii-heat .m-pii .m-ic, body.focus .m-full .m-ic{transform:scale(1.12)}
.m-btn .m-lb{font-size:10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%}
.m-ic-stop, .m-lb-stop{display:none}
body.playing .m-play .m-ic-play, body.playing .m-play .m-lb-play{display:none}
body.playing .m-play .m-ic-stop, body.playing .m-play .m-lb-stop{display:inline}
body.playing .m-play{color:var(--pii)}
body.pii-heat .m-pii{color:var(--pii)}
/* Full ↔ Exit swap (icon + label) driven by body.focus, like Play↔Stop */
.m-ic-exit, .m-lb-exit{display:none}
body.focus .m-full .m-ic-full, body.focus .m-full .m-lb-full{display:none}
body.focus .m-full .m-ic-exit, body.focus .m-full .m-lb-exit{display:inline}
body.focus .m-full{color:var(--accent)}
.m-more[aria-expanded="true"]{color:var(--accent)}
/* landscape has a WIDE bar with room to spare — surface the common actions inline (Theme/Reset/Full-Exit)
   instead of hiding them behind More. Portrait keeps the lean 5. More then only holds Search + Legend. */
.m-land{display:none}
body.is-phone.landscape .mobile-bar .m-land{display:flex}
body.is-phone.landscape .ms-grid{display:none}   /* Theme/Reset/Full are on the bar now; sheet = search + legend */

body.is-phone .mobile-sheet{display:block; position:fixed; left:0; right:0; bottom:0; z-index:58; transform:translateY(115%);
  transition:transform .28s ease; background:var(--bg1); border-top-left-radius:18px; border-top-right-radius:18px;
  border-top:1px solid var(--bd); box-shadow:0 -16px 44px rgba(0,0,0,.3); padding:8px 14px calc(16px + env(safe-area-inset-bottom));
  touch-action:none; overscroll-behavior:contain}   /* JS handles the drag; block the browser's pull-to-refresh/scroll */
.ms-search{touch-action:auto}   /* keep the search field normally interactive */
body.dark.is-phone .mobile-sheet{background:#0b1122}
body.is-phone.sheet-open .mobile-sheet{transform:translateY(0)}
.ms-grab{width:40px; height:5px; border-radius:3px; background:var(--bd2); margin:2px auto 12px; touch-action:none}
.ms-searchrow{display:flex; gap:8px; margin-bottom:12px}
.ms-search{flex:1 1 auto; min-width:0; height:44px; border-radius:12px; border:1px solid var(--bd2); background:var(--bg0); color:var(--tx); padding:0 14px; font-size:15px}
.ms-searchbtn{flex:0 0 48px; height:44px; border-radius:12px; border:0; background:var(--accent); color:#fff; font-size:18px; cursor:pointer; display:grid; place-items:center; -webkit-tap-highlight-color:transparent; transition:transform .12s ease}
.ms-searchbtn:active{transform:scale(.92)}
.ms-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:8px}
.ms-hint{margin:12px 2px 2px; font-size:11.5px; color:var(--tx3); text-align:center}
.ms-item{display:flex; flex-direction:column; align-items:center; gap:6px; padding:12px 6px; border-radius:12px; border:1px solid var(--bd);
  background:var(--bg2); color:var(--tx); font-size:12px; font-weight:600; cursor:pointer; -webkit-tap-highlight-color:transparent}
.ms-item:active{background:color-mix(in srgb,var(--accent) 15%, transparent)}
.ms-item .ms-ic{font-size:18px}
.ms-wide{grid-column:span 2; flex-direction:row; justify-content:center; gap:8px}
.ms-legend{display:flex; flex-wrap:wrap; gap:8px 12px; margin-top:12px; padding-top:12px; border-top:1px solid var(--bd); font-size:11.5px; color:var(--tx2)}
.ms-copyright{margin-top:12px; font-size:11px; font-weight:600; opacity:.6; text-align:center; color:var(--tx3)}
.mlg{display:inline-flex; align-items:center; gap:6px}
.mlg-dot{width:9px; height:9px; border-radius:50%; flex:0 0 auto}
body.is-phone.sheet-open .mobile-sheet-backdrop{display:block; position:fixed; inset:0; z-index:57; background:rgba(4,7,20,.5)}
body.is-phone.drawer-open .mobile-bar{display:none}   /* detail sheet is open (has its own ✕) — don't fight it */
body.is-phone.panel-open .mobile-bar{display:none}    /* options drawer open — don't cover its Generate/Clear buttons */
/* landscape side-notch safe areas so the bar/header clear the cutout */
body.is-phone.landscape .mobile-bar{padding-left:max(6px,env(safe-area-inset-left)); padding-right:max(6px,env(safe-area-inset-right))}
body.is-phone.landscape header{padding-left:max(12px,env(safe-area-inset-left)); padding-right:max(12px,env(safe-area-inset-right))}

/* ---- 2.0 landscape phone: reclaim vertical space (height is the scarce axis) ---- */
body.is-phone.landscape header{padding:6px 12px 0}
body.is-phone.landscape .title{font-size:16px}
body.is-phone.landscape .dl-tabs{margin-top:6px}
body.is-phone.landscape .dl-tab{padding:6px 10px}
body.is-phone.landscape .dl-tab-d{display:none}          /* drop tab sub-labels — save a row */
body.is-phone.landscape .m-btn{height:44px}
body.is-phone.landscape .stage-area{padding-bottom:calc(52px + env(safe-area-inset-bottom))}

/* ---- 2.0 detail drawer as a real bottom sheet: grab handle + room for swipe-to-dismiss ---- */
body.is-phone .drawer{border-top-left-radius:18px; border-top-right-radius:18px; transition:transform .26s ease}
body.is-phone .drawer::before{content:""; position:sticky; top:0; display:block; width:42px; height:5px; margin:8px auto 2px;
  border-radius:3px; background:var(--bd2); z-index:2}
body.is-phone .drawer.dragging{transition:none}          /* follow the finger 1:1 while dragging */

@media print{
  header, .main, footer{display:none !important}
  body{background:#fff; margin:0}
  .report{display:block; padding:14mm}
  @page{margin:0}   /* KEEP 0. Confirmed on prod: margin:0 = no browser header/footer; any margin >0 gives Chrome
                       room to print its date/title/URL/page-number chrome. The page gap is not worth that. */
  /* never strand a heading at the bottom of a page away from its content */
  .report h1,.report h2,.report h3,.r-sub{break-after:avoid; page-break-after:avoid}
  .r-head{break-after:avoid; page-break-after:avoid}
  .r-sys{break-inside:avoid; page-break-inside:avoid}
  .r-table{break-inside:auto}
  .r-table tr{break-inside:avoid; page-break-inside:avoid}
  .r-table thead{break-inside:avoid}
  /* the embedded live diagram: force its dark bg + node/edge colours to actually print (browsers strip
     backgrounds by default), and keep the whole map on one page */
  .r-dgm-box{break-inside:avoid; page-break-inside:avoid}
  /* keep EVERY colour in the report (legend dots, PII badges, class chips, node dots, the diagram) — browsers
     strip background colours in print by default, which is why the colour coding was missing. */
  .report, .report *{-webkit-print-color-adjust:exact !important; print-color-adjust:exact !important; color-adjust:exact !important}
}

/* ============================================================
   REDESIGN FEATURES — risk line, PII summary, completeness, stamp, search
   ============================================================ */
/* drawer: "Risk: …" line under the node header */
.risk-line{font-size:11.5px; font-weight:600; margin:4px 0 8px; display:inline-flex; gap:7px; align-items:center}
.risk-line::before{content:""; width:9px; height:9px; border-radius:50%; background:#5b9e7d}
.risk-line[data-risk="high"]{color:#c2334a} .risk-line[data-risk="high"]::before{background:#FF5A6E}
.risk-line[data-risk="med"]{color:#9a6a10}  .risk-line[data-risk="med"]::before{background:#FFB020}
.risk-line[data-risk="low"]{color:#3f7a5f}  .risk-line[data-risk="low"]::before{background:#5b9e7d}
/* drawer: PII exposure summary (shown when Highlight-PII is on) */
.pii-summary{font-size:12.5px; color:var(--tx); line-height:1.5; margin:8px 0 4px; padding:9px 11px; border-radius:9px;
  background:color-mix(in srgb,var(--pii) 12%, transparent); border:1px solid color-mix(in srgb,var(--pii) 35%, transparent)}
.pii-summary b{color:var(--pii); font-size:14px}
/* PII exposure breakdown — high / medium node lists */
.pii-risk{font-size:11.5px; line-height:1.45; margin-top:7px; color:var(--tx2)}
.pii-risk .pr-lab{font-weight:800; text-transform:uppercase; letter-spacing:.4px; font-size:10px}
.pii-risk.hi .pr-lab{color:#c2334a} .pii-risk.md .pr-lab{color:#9a6a10}
body.dark .pii-risk.hi .pr-lab{color:#ff9aa6} body.dark .pii-risk.md .pr-lab{color:#ffce80}
/* form: completeness meter */
.completeness{margin:6px 0 2px; padding:10px 11px; border:1px solid var(--bd); border-radius:10px; background:var(--panel)}
.cm-top{display:flex; justify-content:space-between; align-items:center; font-size:11px; font-weight:600; color:var(--tx2); margin-bottom:6px}
.cm-pct{color:var(--brand2); font-weight:800}
.cm-bar{height:6px; border-radius:6px; background:var(--panel2); overflow:hidden}
.cm-bar i{display:block; height:100%; border-radius:6px; background:linear-gradient(90deg,#7a3dff,#9b4dff); transition:width .3s ease}
/* header: last-generated timestamp (custom tab only) */
.gen-stamp{font-size:11px; color:var(--tx3); margin-top:5px; font-weight:600}
.gen-stamp:empty{display:none}
/* controls: search systems input */
.sys-search{border:1px solid var(--bd2); background:#fff; color:var(--tx); padding:8px 12px; border-radius:9px;
  font-size:13px; font-weight:500; min-width:160px; box-shadow:0 1px 2px rgba(28,32,64,.06)}
.sys-search::placeholder{color:var(--tx3)}
.sys-search:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px rgba(122,61,255,.15)}
@media (max-width:900px){ .sys-search{flex:0 0 auto; height:38px; min-width:140px} }

/* ============================================================
   DARK THEME  (body.dark)  — the original neon look, toggled on
   ============================================================ */
body.dark{
  /* SOC console: deepened toward #090B14 for a darker security-ops feel */
  --bg0:#06080f; --bg1:#080a16; --bg2:#0a0e22;
  --panel:rgba(255,255,255,.045); --panel2:rgba(255,255,255,.07);
  --bd:rgba(255,255,255,.12); --bd2:rgba(255,255,255,.22);
  --tx:#e8edff; --tx2:#9fb0d6; --tx3:#6f80a8;
  --pii:#fb7185; --pay:#fbbf24; --order:#38bdf8; --beh:#a78bfa; --mkt:#34d399; --cred:#94a3b8;
  --shield:#7dd3fc; --brand:#7dd3fc; --brand2:#a78bfa;
  color-scheme:dark;
  background:radial-gradient(1200px 600px at 15% -10%, #0d1734 0%, transparent 55%),
    radial-gradient(1000px 700px at 100% 0%, #0f1d44 0%, transparent 50%),
    linear-gradient(160deg,var(--bg0),var(--bg1) 55%,var(--bg2));
}
body.dark header{background:linear-gradient(180deg,rgba(8,12,30,.7),rgba(8,12,30,0))}
body.dark .title{background:linear-gradient(90deg,#8b5cf6,#a78bfa 45%,#7c3aed 90%);-webkit-background-clip:text;background-clip:text;color:transparent}   /* Shiprocket brand violet */
body.dark button.ctl{background:var(--panel2); box-shadow:none}
body.dark button.ctl:hover{border-color:#7dd3fc; background:rgba(125,211,252,.14)}
body.dark button.ctl.on{background:linear-gradient(90deg,rgba(167,139,250,.3),rgba(125,211,252,.3)); border-color:#a78bfa; color:var(--tx); box-shadow:0 0 16px rgba(167,139,250,.35)}
body.dark button.ctl.play{background:linear-gradient(90deg,#7c3aed,#2563eb)}
body.dark button.ctl.pdf{background:linear-gradient(90deg,#0ea5e9,#22c55e)}
body.dark .dot{box-shadow:0 0 8px currentColor}
body.dark .form-panel{background:linear-gradient(180deg,rgba(13,19,46,.62),rgba(9,14,34,.50)); box-shadow:inset 0 1px 0 rgba(255,255,255,.06)}
body.dark.has-flow .form-panel.open, body.dark.has-flow .form-panel.pin{box-shadow:10px 0 34px rgba(0,0,0,.55)}
body.dark .rail-arrow{background:linear-gradient(135deg, rgba(125,211,252,.20), rgba(167,139,250,.18) 55%, rgba(251,113,133,.16)); color:#eaf3ff;
  box-shadow:0 0 0 1px rgba(125,211,252,.35), 0 8px 26px -6px rgba(99,102,241,.55), inset 0 0 14px -6px rgba(125,211,252,.6)}
body.dark .rail-arrow span{background:linear-gradient(90deg,#7dd3fc,#a78bfa); -webkit-background-clip:text; background-clip:text; color:transparent}
body.dark .rail-arrow::before{background:linear-gradient(180deg,#7dd3fc,#a78bfa,#fb7185)}
body.dark .req{color:#fca5a5}
body.dark .grp{color:#fcd34d}
body.dark .cust{background:rgba(255,255,255,.03)}
body.dark .fld select, body.dark .fld input[type=text], body.dark .fld input.combo{background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.02)); color-scheme:dark}
body.dark .fld input.combo:focus{border-color:#7dd3fc; box-shadow:0 0 0 1px rgba(125,211,252,.4), 0 0 14px -4px rgba(125,211,252,.5)}
body.dark .combo-pop{background:linear-gradient(180deg,rgba(18,28,62,.98),rgba(10,18,46,.98)); box-shadow:0 16px 38px rgba(0,0,0,.6)}
body.dark .combo-opt:hover{background:linear-gradient(90deg,rgba(125,211,252,.18),rgba(167,139,250,.16)); box-shadow:inset 0 0 0 1px rgba(125,211,252,.25)}
body.dark .combo-opt.custom b{color:#7dd3fc}
body.dark .combo-pop::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14)}
body.dark .chip-sel{background:linear-gradient(90deg,rgba(45,212,191,.22),rgba(56,189,248,.18)); border-color:rgba(45,212,191,.5); color:var(--tx)}
body.dark .chip-sel .x:hover{color:#fff}
body.dark .chip{background:color-mix(in srgb,var(--cc,#888) 22%, transparent); border-color:color-mix(in srgb,var(--cc,#888) 45%, transparent)}
body.dark .multi{background:rgba(255,255,255,.03)}
body.dark .edge-base{stroke:rgba(148,163,184,.15)}
body.dark .edge-flow{filter:drop-shadow(0 0 3px var(--c))}   /* subtle SOC glow on the deepened backdrop */
body.dark .g-edge.focus .edge-base{stroke:rgba(255,255,255,.25)}
body.dark .node{background:linear-gradient(180deg,var(--panel2),var(--panel)); box-shadow:0 8px 26px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06), 0 0 18px -10px color-mix(in srgb,var(--accent) 65%, transparent)}
body.dark .node:hover{box-shadow:0 0 0 1px var(--accent), 0 0 26px -2px var(--accent)}
body.dark .node.focus{box-shadow:0 0 0 1px var(--accent),0 0 30px -2px var(--accent)}
body.dark .node-ic{background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 55%, transparent), rgba(255,255,255,.05)); border:1px solid color-mix(in srgb,var(--accent) 55%, transparent)}
body.dark .node-ic.has-logo, body.dark .di.has-logo{background:#fff; border-color:rgba(255,255,255,.5)}
body.dark .node-ic.emoji, body.dark .di.emoji{background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 55%, transparent), rgba(255,255,255,.05))}
body.dark .cchip{background:linear-gradient(180deg,rgba(255,255,255,.08),rgba(255,255,255,.03))}
body.dark .node .badge{color:#2a0710; box-shadow:0 0 10px var(--pii)}
body.dark .elabel{background:rgba(10,16,38,.92); box-shadow:0 3px 10px rgba(0,0,0,.4)}
body.dark .stage.soft .node:not(.focus){opacity:.18; filter:saturate(.4)}
body.dark .stage.soft .g-edge:not(.focus){opacity:.12}
body.dark .caption{background:linear-gradient(90deg,rgba(124,58,237,.92),rgba(37,99,235,.92)); box-shadow:0 10px 30px rgba(0,0,0,.5)}
body.dark .drawer{background:linear-gradient(180deg,rgba(13,19,46,.62),rgba(9,14,34,.50)); box-shadow:inset 0 1px 0 rgba(255,255,255,.06)}
body.dark .drawer.open{box-shadow:-12px 0 40px rgba(0,0,0,.5), inset 1px 0 0 rgba(125,211,252,.25)}
body.dark .dh .di{background:radial-gradient(circle at 30% 25%, color-mix(in srgb,var(--accent) 55%, transparent), rgba(255,255,255,.05)); border:1px solid color-mix(in srgb,var(--accent) 60%, transparent)}
body.dark .shares li .to{color:#cde3ff}
body.dark .guards li{background:linear-gradient(90deg,rgba(125,211,252,.09),transparent); border:1px solid rgba(125,211,252,.22); color:#e9f4ff}
body.dark .risk{color:#ffd9d9; background:rgba(251,113,133,.12); border:1px solid rgba(251,113,133,.4)}
body.dark .risk b{color:#ffb3bd}
body.dark .drawer::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14)}
/* dark overrides for redesign features */
body.dark .risk-line[data-risk="high"]{color:#ff9aa6}
body.dark .risk-line[data-risk="med"]{color:#ffce80}
body.dark .risk-line[data-risk="low"]{color:#88c7a8}
body.dark .cm-bar i{background:linear-gradient(90deg,#7dd3fc,#a78bfa)}
body.dark .sys-search{background:var(--panel2); box-shadow:none}
body.dark .sys-search:focus{border-color:#7dd3fc; box-shadow:0 0 0 1px rgba(125,211,252,.4)}

/* ============================================================
   DATA LENS GO-LIVE — Standard README (C) + guardrail popup (E)
   ============================================================ */
/* C: Standard tab = scrollable stack (hero → diagram → rest of guide → disclaimer). README uses the
   reference readme's OWN styling, scoped under .dl-readme so it can't leak into app chrome. */
body.tab-standard .stage-area{overflow-y:auto; overflow-x:hidden}
body.tab-standard #wrap{height:78vh; min-height:520px; max-width:1180px; margin:0 auto}     /* diagram lives in the same centered column as the hero/guide (never a full-width frame) */
/* Standard desktop: the detail drawer is a 350px right overlay. Reserve its gutter on the scroll area and let
   the guide + diagram FILL up to it — kills the big right gap on wide screens and stops the guide sliding under
   the drawer on laptops. Mobile (≤560) uses a full-screen drawer, and full-screen (focus) reserves via fit(). */
@media (min-width:561px){
  /* Standard desktop: equal gutters — empty left ↔ right drawer. The guide/diagram are auto-width blocks with
     fixed 366px margins, so they FILL the middle and their right edge sits ~16px from the drawer (matching the
     small internal gaps). Margins (not stage-area padding) so the fill is reliable. */
  body.tab-standard:not(.focus) #wrap{ max-width:none; width:auto; margin-left:340px; margin-right:340px; height:auto; aspect-ratio:1.9; min-height:380px; }
  body.tab-standard:not(.focus) .dl-readme{ max-width:none !important; width:auto !important; margin-left:340px !important; margin-right:340px !important; }
}
/* PHONE (incl. LANDSCAPE, which is >561px wide and would otherwise hit the desktop rule above):
   the 340px side-gutters + fixed 1.9 aspect would crush the diagram into a strip — reset to full width
   and a fitting, scroll-friendly height. Standard on a phone uses the bottom-sheet drawer (no side gutter). */
body.is-phone.tab-standard #wrap,
body.is-phone.tab-standard .dl-readme{ margin-left:0 !important; margin-right:0 !important; width:auto !important; max-width:none !important; }
/* NORMAL (not full-screen): make the frame HUG the wide diagram (~1.7:1) so there are no empty top/bottom
   bands. Boxes stay overview-sized in portrait — pinch to zoom, or tap Full to rotate to landscape. */
body.is-phone.tab-standard:not(.focus) #wrap{ aspect-ratio:1.7 !important; height:auto !important; min-height:0 !important }
/* FULL screen (rotated to landscape): let the diagram fill the whole viewport */
body.is-phone.focus #wrap{ flex:1 1 auto; height:auto !important; aspect-ratio:auto !important; min-height:0 !important; margin:0 !important; max-width:none !important }
body.tab-standard .stage-wrap{touch-action:auto; cursor:default; border:1px solid var(--bd); border-radius:14px; overflow:hidden}   /* fixed reference: page scrolls over it, no drag/pan */
.dl-readme{display:none}
body.tab-standard .dl-readme, .r-readme{display:block}
/* --- reference palette + look, scoped --- */
.dl-readme{
  /* light (Shiprocket default) palette — the guide now follows the theme toggle */
  --bg:#ffffff; --panel:#f6f8fe; --panel2:#eef1fb;
  --border:rgba(28,32,64,.12); --border2:rgba(28,32,64,.18);
  --text:#252a4a; --muted:#5b6180; --heading:#141838;
  --accent:#6d8bff; --accent2:#8b5cf6; --cyan:#3f8bff;
  color:var(--text); background:var(--bg);
  border:1px solid var(--border); border-radius:14px; padding:14px 30px; max-width:1180px; margin:0 auto;
  line-height:1.6; font-size:14px}
body.dark .dl-readme{
  --bg:#0a0f24; --panel:#121a38; --panel2:#162043;
  --border:rgba(255,255,255,.09); --border2:rgba(255,255,255,.14);
  --text:#e8ecf6; --muted:#9aa6c4; --heading:#eaf1ff; --cyan:#5cc6ff}
body.tab-standard #standardHero{margin-bottom:12px}
body.tab-standard #standardGuide{margin-top:14px}
.dl-readme .hero{padding:2px 0 2px}
.dl-readme .eyebrow{display:inline-block; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); border:1px solid var(--border2); border-radius:999px; padding:5px 12px; margin-bottom:14px}
.dl-readme h1.title{font-size:46px; line-height:1.05; margin:.08em 0 .12em; font-weight:850; letter-spacing:-.5px;
  background:linear-gradient(100deg,#8b5cf6,#a78bfa 55%,#7c3aed); -webkit-background-clip:text; background-clip:text; color:transparent}   /* Shiprocket brand violet */
.dl-readme .tagline{font-size:18px; color:var(--heading); font-weight:600; margin:.2em 0 .4em}   /* use full card width (matches the sections below) — no early wrap / mid-word break */
.dl-readme .lede{font-size:15px; color:var(--muted)}
.dl-readme section{padding:16px 0 2px; border-top:1px solid var(--border); margin-top:14px}
.dl-readme section:first-of-type{border-top:none; margin-top:2px; padding-top:4px}
.dl-readme h2{font-size:23px; color:var(--heading); margin:6px 0 6px; font-weight:780; letter-spacing:-.2px}
.dl-readme h2 .hbar{display:inline-block; width:28px; height:4px; border-radius:3px; vertical-align:middle; margin-right:11px; background:linear-gradient(90deg,var(--accent2),var(--accent))}
.dl-readme h3{font-size:16px; color:var(--heading); margin:18px 0 4px; font-weight:700}
.dl-readme h4{margin:0 0 6px; font-size:15px; color:var(--heading)}
.dl-readme p{margin:8px 0; color:var(--text)}
.dl-readme .muted{color:var(--muted)}
.dl-readme .dl-note{position:relative; margin:2px 0; padding:15px 18px 15px 52px; border:1px solid rgba(245,166,35,.55); border-radius:12px;
  background:rgba(245,166,35,.10); box-shadow:0 0 22px -6px rgba(245,166,35,.45), inset 0 0 0 1px rgba(245,166,35,.10);
  font-size:13px; line-height:1.6; color:var(--text)}
.dl-readme .dl-note::before{content:"⚠"; position:absolute; left:16px; top:13px; font-size:20px; color:#f5a623; filter:drop-shadow(0 0 6px rgba(245,166,35,.6))}
.dl-readme .gloss-sub{font-size:16px; font-weight:700; color:var(--heading); margin:26px 0 4px}
.dl-readme .gloss-sub:first-of-type{margin-top:14px}
.dl-readme .grid{display:grid; gap:15px}
.dl-readme .g2{grid-template-columns:repeat(2,1fr)}
.dl-readme .g3{grid-template-columns:repeat(3,1fr)}
@media(max-width:820px){.dl-readme .g2,.dl-readme .g3{grid-template-columns:1fr}}
.dl-readme .card{background:linear-gradient(180deg,var(--panel),var(--panel2)); border:1px solid var(--border); border-radius:14px; padding:16px 18px; box-shadow:0 10px 30px rgba(0,0,0,.35)}
.dl-readme .card h4{margin:0 0 6px}
.dl-readme .pill{display:inline-block; font-size:11.5px; font-weight:700; letter-spacing:.04em; padding:3px 10px; border-radius:999px; margin-bottom:10px; color:#fff}
.dl-readme .pill.std{background:linear-gradient(90deg,#7c3aed,#3b5bf6)}
.dl-readme .pill.mine{background:rgba(46,207,158,.16); color:#46e3b0; border:1px solid rgba(46,207,158,.3)}
.dl-readme .legend{display:flex; flex-wrap:wrap; gap:10px; margin:14px 0 4px}
.dl-readme .chip{display:flex; align-items:center; gap:8px; background:var(--panel); border:1px solid var(--border); border-radius:999px; padding:7px 13px; font-size:13.5px}
.dl-readme .dot{width:11px; height:11px; border-radius:50%}
.dl-readme table{width:100%; border-collapse:collapse; margin:12px 0; font-size:14px; background:var(--panel); border:1px solid var(--border); border-radius:12px; overflow:hidden}
.dl-readme th,.dl-readme td{text-align:left; padding:11px 14px; border-bottom:1px solid var(--border); vertical-align:top; color:var(--text)}
.dl-readme thead th{background:rgba(109,139,255,.14); color:var(--heading); font-size:12.5px; letter-spacing:.04em; text-transform:uppercase}
.dl-readme tr:last-child td{border-bottom:none}
.dl-readme td.k{font-weight:700; color:var(--heading); white-space:nowrap}
/* Small screens: the 2-column glossary/tables don't fit — stack each row (name above, description below). */
/* glossary tables stack into blocks on phones (portrait + landscape) */
body.is-phone .dl-readme table, body.is-phone .dl-readme tbody, body.is-phone .dl-readme tr, body.is-phone .dl-readme td{display:block; width:auto}
body.is-phone .dl-readme thead{position:absolute; left:-9999px}   /* hide the header row; the bold name labels each block */
body.is-phone .dl-readme tr{border-bottom:1px solid var(--border); padding:2px 0}
body.is-phone .dl-readme tr:last-child{border-bottom:none}
body.is-phone .dl-readme td{border-bottom:none; padding:4px 14px}
body.is-phone .dl-readme td.k{white-space:normal; padding-top:12px; font-size:14.5px}
body.is-phone .dl-readme td:not(.k){padding-bottom:12px; color:var(--text); opacity:.92}
/* tighter guide side-padding + wordmark on a narrow screen */
body.is-phone .dl-readme{padding-left:16px; padding-right:16px}
.dl-readme .swatch{display:inline-block; width:10px; height:10px; border-radius:3px; margin-right:8px; vertical-align:middle}
.dl-readme ul.clean{list-style:none; padding:0; margin:10px 0}
.dl-readme ul.clean li{position:relative; padding:7px 0 7px 26px; color:var(--text)}
.dl-readme ul.clean li::before{content:""; position:absolute; left:4px; top:14px; width:7px; height:7px; border-radius:50%; background:linear-gradient(90deg,var(--accent2),var(--accent))}
.dl-readme ul.clean li b{color:var(--heading)}
.dl-readme ol.steps{list-style:none; counter-reset:s; padding:0; margin:14px 0}
.dl-readme ol.steps li{counter-increment:s; position:relative; padding:10px 0 10px 46px; border-bottom:1px dashed var(--border)}
.dl-readme ol.steps li:last-child{border-bottom:none}
.dl-readme ol.steps li::before{content:counter(s); position:absolute; left:0; top:9px; width:30px; height:30px; border-radius:9px; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:14px; color:#fff; background:linear-gradient(135deg,var(--accent2),var(--accent))}
.dl-readme .callout{border-radius:13px; padding:16px 18px; margin:14px 0; border:1px solid; display:flex; gap:12px}
.dl-readme .callout .ic{font-size:18px; line-height:1.2}
.dl-readme .callout.info{background:rgba(109,139,255,.10); border-color:rgba(109,139,255,.32)}
.dl-readme .callout.info b{color:#9db4ff}
.dl-readme .callout .muted,.dl-readme .callout p{font-size:13.5px; color:var(--muted); margin:0}
.dl-readme .num{display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; border-radius:8px; font-weight:800; font-size:13px; color:#fff; background:linear-gradient(135deg,var(--accent2),var(--accent)); margin-right:10px}
.dl-readme .comp h3{display:flex; align-items:center}
.dl-readme dl{margin:10px 0}
.dl-readme dl div{padding:9px 0; border-bottom:1px solid var(--border)}
.dl-readme dl div:last-child{border-bottom:none}
.dl-readme dt{font-weight:700; color:var(--heading)}
.dl-readme dd{margin:2px 0 0; color:var(--muted); font-size:14px}
/* bottom disclaimer = the reference's hero ⚠️ warn callout, moved to the very bottom */
.dl-disclaimer{display:none}
body.tab-standard .dl-disclaimer{display:flex; gap:11px; align-items:flex-start; max-width:1040px; margin:14px auto 28px; padding:14px 16px; border-radius:13px; font-size:13px; line-height:1.5; color:#cbb079; background:rgba(245,166,35,.10); border:1px solid rgba(245,166,35,.35)}
.dl-disclaimer .ic{font-size:17px; line-height:1.2}
.dl-disclaimer b{color:#f3b65a}
/* README reused inside the printable report: re-theme to light-on-white, no outer frame */
.r-readme{margin:6px 0 14px}
.report .dl-readme{--bg:#fff; --panel:#f7f9ff; --panel2:#eef1fa; --border:rgba(20,30,70,.12); --border2:rgba(20,30,70,.2); --text:#1f2742; --muted:#5b678a; --heading:#16204a; background:#fff; color:#1f2742; border:0; border-radius:0; padding:0; max-width:none}
.report .dl-readme .card{box-shadow:none}
.report .r-why{font-style:italic; font-size:11px; color:#475569; margin:4px 0 6px}
.report .r-gpii{font-size:11px; color:#0f172a; margin:0 0 6px}
/* E: per-system guardrail ⓘ button + popup */
.gd-info{margin-left:2px; border:0; background:transparent; color:var(--brand2); cursor:pointer; font-size:13px; line-height:1; padding:0 2px;
  border-radius:50%; transition:.15s}
.gd-info:hover{color:var(--brand); transform:scale(1.15)}
.gd-info:focus-visible{outline:2px solid var(--brand); outline-offset:2px}
.gd-overlay{position:fixed; inset:0; z-index:80; display:grid; place-items:center; padding:18px;
  background:rgba(6,8,15,.55); backdrop-filter:blur(3px)}
.gd-modal{position:relative; width:min(560px,94vw); max-height:86dvh; overflow-y:auto; background:var(--bg0); color:var(--tx);
  border:1px solid var(--bd2); border-radius:16px; padding:20px 22px 22px; box-shadow:0 30px 70px -20px rgba(0,0,0,.6)}
body.dark .gd-modal{background:linear-gradient(180deg,#0e1430,#0a1024)}
.gd-x{position:absolute; top:12px; right:12px; width:30px; height:30px; border-radius:50%; border:1px solid var(--bd2);
  background:var(--panel); color:var(--tx); cursor:pointer; font-size:14px; line-height:1}
.gd-x:hover{border-color:var(--brand); color:var(--brand2)}
.gd-head h2{font-size:18px; font-weight:800; margin:0 26px 2px 0}
.gd-head .gd-sub{font-size:11px; font-weight:800; letter-spacing:1px; text-transform:uppercase; color:var(--tx3)}
.gd-why{font-style:italic; font-size:13px; line-height:1.55; color:var(--tx2); margin:12px 0 8px}
.gd-pii{font-size:12.5px; color:var(--tx); margin:0 0 10px; padding:7px 10px; border-radius:8px;
  background:color-mix(in srgb,var(--pii) 10%, transparent); border:1px solid color-mix(in srgb,var(--pii) 28%, transparent)}
.gd-pii b{color:var(--pii)}
/* draw our own bullet — don't rely on the browser default list-style (a host theme's
   `ul{list-style:none}` reset strips it, and display:flex suppresses native markers) */
.gd-points{margin:0; padding-left:0; list-style:none; display:flex; flex-direction:column; gap:7px}
.gd-points li{position:relative; padding-left:18px; font-size:13px; line-height:1.5; color:var(--tx)}
.gd-points li::before{content:""; position:absolute; left:3px; top:8px; width:6px; height:6px; border-radius:50%; background:var(--brand2)}
/* phone (portrait + landscape) diagram interaction + modal sizing */
body.is-phone .gd-modal{width:96vw; max-height:92dvh}
/* vertical drag scrolls the page (so the guide/disclaimer below the diagram stay reachable);
   horizontal drag pans the wide pipeline and pinch still zooms (both handled in JS). */
body.is-phone.tab-standard .stage-wrap{touch-action:pan-y; cursor:grab}
body.is-phone.tab-standard .stage-wrap.grabbing{cursor:grabbing}
body.is-phone .ctl{min-height:40px}   /* comfortable tap target (for any toolbar ctl still shown, e.g. tablets) */
/* Focus / presentation mode (⛶ Full screen at ANY width, or phone Play): show ONLY the diagram + its
   controls, filling the screen — hide the intro/guide text, tabs, legend and footer. Reverts on exit. */
body.focus .title,
body.focus .title-sub,
body.focus .gen-stamp,
body.focus .dl-tabs,
body.focus .legend,
body.focus footer,
body.focus #standardHero,
body.focus #standardGuide{display:none}
body.focus header{padding:8px 14px 0}
body.focus .bar{margin-top:6px}
body.focus .stage-area{display:flex; flex-direction:column; overflow:hidden; padding:8px}
body.focus.tab-standard #wrap{height:auto; flex:1 1 auto; min-height:0; max-width:none; border:0; border-radius:12px}
@media (max-width:400px){ .dl-tab-d{font-size:10px} .dl-tab-t{font-size:14px} }

/* phones: one-time interaction hint, floats over the diagram then fades */
.dl-touch-hint{position:absolute; left:50%; bottom:14px; transform:translateX(-50%);
  max-width:92%; padding:8px 14px; border-radius:999px; font-size:12px; font-weight:600; white-space:nowrap;
  background:rgba(13,19,46,.92); color:#eaf3ff; box-shadow:0 6px 20px rgba(0,0,0,.3); z-index:30;
  pointer-events:none; opacity:0; animation:dlHintIn .28s ease forwards}
.dl-touch-hint.out{opacity:0; transform:translateX(-50%) translateY(6px); transition:opacity .5s ease, transform .5s ease}
@keyframes dlHintIn{from{opacity:0; transform:translateX(-50%) translateY(6px)} to{opacity:1; transform:translateX(-50%) translateY(0)}}
