/* ═══════════════════════════════════════════════════════
   VANTAGE OS · 3D structure view (home, #structure)
   The sample session 4471-B as a model of 212 Linden Ave, Unit 1.
   Reuses the .vos chrome from vantage.css (header, basis ribbon,
   toast, level rail, card, dock); everything new is v3- prefixed.
   vos3d.js draws the model into .v3-canvas and pins the .v3-tags
   to points in it. Pictures of the model (.v3-poster) hold the place
   while it loads and are the whole view where WebGL is off.
   ═══════════════════════════════════════════════════════ */
main section.v3-sec{padding-bottom:clamp(40px,6vw,72px); overflow:hidden;}
.v3-head{text-align:center;}
.v3-head h2{max-width:22ch; margin-left:auto; margin-right:auto;}
.v3-head .lede{margin:0 auto; max-width:60ch;}
.v3-head .eyebrow{margin:0 auto 20px;}

/* the tablet leans back as it arrives and stands up as it reaches the middle */
.v3-stage{max-width:1180px; margin:clamp(30px,4.6vw,56px) auto 0; padding:0 var(--pad); perspective:1900px; perspective-origin:50% 0%;}
.v3-tilt{--v3t:0; transform-origin:50% 0%; transform:rotateX(calc(var(--v3t) * 26deg)) scale(calc(1 - var(--v3t) * 0.07)); will-change:transform;}
.v3-glow{position:relative;}
.v3-glow::before{content:""; position:absolute; left:8%; right:8%; top:12%; bottom:-6%; z-index:-1; border-radius:50%; pointer-events:none;
  background:radial-gradient(closest-side, rgba(76,141,255,0.20), rgba(76,141,255,0.06) 55%, transparent); filter:blur(30px);}

.vos.v3{padding:8px; border-radius:26px; background:#0B0D11; display:flex; flex-direction:column; gap:6px; container-type:inline-size;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.08), 0 1px 0 rgba(255,255,255,0.06), 0 60px 120px -40px rgba(0,0,0,0.95), 0 30px 60px -30px rgba(20,40,90,0.5);}
.v3 .vos-head .vos-addr{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;}

/* the map: the model, its pinned tags and the map chrome */
/* An explicit height, not aspect-ratio with max-height: Safari narrows a flex
   item to keep its ratio when max-height clamps it, which left the map thinner
   than the tablet on iPad. cqw is the tablet's own width. */
.v3-map{padding:0; flex:none; width:100%; height:min(50vw, 560px); height:min(52.5cqw, max(380px, calc(100svh - 360px))); touch-action:pan-y; cursor:grab; outline:none; isolation:isolate;
  background:radial-gradient(120% 90% at 50% 40%, #0D1118, #08090D 70%);}
.v3-map.drag{cursor:grabbing;}
.v3-map.hot{cursor:pointer;}
.v3-map:focus-visible{box-shadow:inset 0 0 0 2px var(--accent);}
.v3-canvas{position:absolute; inset:0; width:100%; height:100%; display:block; opacity:0; transition:opacity .8s ease;}
.v3.ready .v3-canvas{opacity:1;}

/* Pictures of the model, one per layer. They are the placeholder while the
   live model loads, and the whole view where WebGL is off, as in iOS Lockdown
   Mode. vos3d.js keeps .v3-pbox the size of the picture inside the map. */
.v3-poster{position:absolute; inset:0; pointer-events:none; transition:opacity .8s ease;}
/* each picture is laid at its own size; the edges feather out so a map wider
   or taller than the picture shows no seam */
.v3-poster img{position:absolute; left:0; top:0; width:100%; height:100%; opacity:0; transition:opacity .5s ease;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent), linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent), linear-gradient(180deg, transparent, #000 6%, #000 94%, transparent);
  mask-composite:intersect;}
.v3-poster img.on{opacity:1;}
.v3.ready .v3-poster{opacity:0;}
.v3-pbox{position:absolute; left:0; top:0; width:100%; height:100%; pointer-events:none;}
.v3-pbox svg{display:block; width:100%; height:100%; overflow:visible;}
.v3-pbox polygon{fill:rgba(76,141,255,0.10); stroke:var(--accent); stroke-width:2.5; stroke-linejoin:round; vector-effect:non-scaling-stroke; opacity:0; transition:opacity .3s ease;}
.v3-pbox polygon.on{opacity:1;}
.v3.flat .v3-map{cursor:default;}
.v3.flat .v3-map.hot{cursor:pointer;}

/* tags pinned to the model */
.v3-tags{position:absolute; inset:0; pointer-events:none; z-index:1; overflow:hidden;}
.v3-tags > *{position:absolute; left:0; top:0; opacity:0; visibility:hidden; transition:opacity .4s ease, visibility .4s; white-space:nowrap;}
.v3-tags > .on{opacity:1; visibility:visible;}
.v3-tags > .off{opacity:0 !important; visibility:hidden !important;}
.v3:not(.ready):not(.flat) .v3-tags{display:none;}

.v3-chip{display:inline-flex; align-items:center; gap:7px; padding:6px 10px 5px; border-radius:999px; font-family:var(--mono); font-size:10px; font-weight:500;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--ink); background:rgba(12,14,19,0.9);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.12), 0 10px 24px -12px rgba(0,0,0,0.9); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);}
.v3-chip i{width:6px; height:6px; border-radius:50%; background:currentColor; flex:none;}
.v3-chip small{font-size:9px; color:var(--faint); letter-spacing:0.12em;}
.v3-chip.occ{color:#CFE0FF; box-shadow:inset 0 0 0 1px rgba(76,141,255,0.55), 0 10px 24px -12px rgba(0,0,0,0.9);}
.v3-chip.occ i{background:var(--accent); box-shadow:0 0 8px var(--accent);}
.v3-chip.dim{color:#AFC1E4; box-shadow:inset 0 0 0 1px rgba(111,143,204,0.45), 0 10px 24px -12px rgba(0,0,0,0.9);}
.v3-chip.dim i{background:#6F8FCC;}
.v3-chip.clr{color:var(--muted);}
.v3-chip.clr i{background:var(--faint);}
.v3-chip.nr{color:var(--red); box-shadow:inset 0 0 0 1px rgba(217,104,94,0.55), 0 10px 24px -12px rgba(0,0,0,0.9);}
.v3-chip.low{color:var(--amber); box-shadow:inset 0 0 0 1px rgba(217,165,79,0.5), 0 10px 24px -12px rgba(0,0,0,0.9);}
.v3-chip.grn{color:var(--green); box-shadow:inset 0 0 0 1px rgba(95,207,132,0.55), 0 10px 24px -12px rgba(0,0,0,0.9);}
.v3-chip.grn i{box-shadow:0 0 8px var(--green); animation:tdot 1.6s ease-in-out infinite;}
/* count tallies are solid, like the 2D view */
.v3-chip.tally{background:var(--accent); color:#06101F; font-weight:600; font-size:11px; letter-spacing:0.08em; box-shadow:0 10px 24px -10px rgba(76,141,255,0.7);}
.v3-chip.tally.dim{background:#6F8FCC;}
/* stacked chips: a reading with a second line */
.v3-chip.two{flex-direction:column; align-items:flex-start; gap:6px; border-radius:12px; padding:9px 12px 9px;}
.v3-chip.two b{font-weight:500; color:var(--ink); letter-spacing:0.12em;}
.v3-chip.two .m{display:block; width:112px; height:4px; border-radius:999px; background:rgba(255,255,255,0.08); overflow:hidden;}
.v3-chip.two .m::after{content:""; display:block; height:100%; width:var(--v,50%); border-radius:999px; background:var(--c,var(--green));}
.v3-chip.big{font-size:11px;}
.v3-chip.big b{font-size:15px; letter-spacing:0.06em;}
.v3-chip.total{align-items:center; text-align:center;}

.v3-side{display:grid; place-items:center; width:22px; height:22px; border-radius:50%; background:#0E1015; box-shadow:inset 0 0 0 1px rgba(233,236,239,0.3);
  font-family:var(--mono); font-size:10.5px; font-weight:600; color:#9BA3AE;}
.v3-entry{display:inline-flex; align-items:center; gap:6px; font-family:var(--mono); font-size:9.5px; font-weight:500; letter-spacing:0.16em; text-transform:uppercase; color:var(--accent2);}
.v3-entry i{width:0; height:0; border:5px solid transparent; border-bottom:7px solid var(--accent2); border-top:0;}
.v3-lock{display:inline-flex; align-items:center; gap:7px; padding:5px 10px; border-radius:999px; font-family:var(--mono); font-size:9.5px; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--faint); background:rgba(12,14,19,0.85); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.08);}
.v3-lock svg{width:10px; height:10px;}
.v3-lock b{font-weight:600; color:var(--muted);}

/* map chrome */
.v3 .vos-toast{top:12px;}
.v3 .vos-lvl{left:12px;}
.v3-ctl{position:absolute; right:12px; top:50%; transform:translateY(-50%); display:grid; gap:6px; z-index:2;}
.v3-ctl button{display:grid; place-items:center; width:38px; height:36px; padding:0; border:0; border-radius:11px; background:rgba(14,16,21,0.92); cursor:pointer;
  box-shadow:inset 0 0 0 1px var(--line); color:var(--muted); font-family:var(--mono); font-size:10px; font-weight:600; letter-spacing:0.06em; transition:color .2s, background .2s, box-shadow .2s;}
.v3-ctl button:hover{color:var(--ink); background:rgba(24,27,34,0.96);}
.v3-ctl button:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}
.v3-ctl button svg{width:15px; height:15px;}
.v3-ctl .n{color:var(--ink); line-height:1.05;}
.v3-ctl .n span{display:grid; justify-items:center; transform:rotate(var(--yaw,0rad)); transition:transform .1s linear;}
.v3-ctl .n span::before{content:""; display:block; width:0; height:0; margin:0 auto 1px; border:4px solid transparent; border-bottom:6px solid var(--red); border-top:0;}
.v3-ctl .dim3{color:var(--accent2); box-shadow:inset 0 0 0 1px rgba(76,141,255,0.45);}
.v3-hint{position:absolute; left:14px; bottom:12px; z-index:2; display:inline-flex; align-items:center; gap:8px; padding:6px 11px 6px 9px; border-radius:999px;
  background:rgba(14,16,21,0.88); box-shadow:inset 0 0 0 1px var(--line); font-family:var(--mono); font-size:9.5px; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--faint); transition:opacity .5s ease; pointer-events:none;}
.v3-hint svg{width:16px; height:16px; color:var(--accent2);}
.v3.touched .v3-hint{opacity:0;}
.v3-tour{position:absolute; right:14px; bottom:12px; z-index:2; width:88px; height:3px; border-radius:999px; background:rgba(255,255,255,0.07); overflow:hidden; transition:opacity .4s;}
.v3-tour i{display:block; height:100%; width:100%; transform-origin:0 50%; transform:scaleX(var(--tp,0)); background:var(--accent2); border-radius:999px;}
.v3.touched .v3-tour, .v3:not(.touring) .v3-tour{opacity:0;}

/* RECORD: the sealed log over the dimmed model */
.v3-log{position:absolute; left:50%; top:52%; z-index:2; width:min(470px, calc(100% - 140px)); transform:translate(-50%,-46%) scale(0.98); opacity:0; visibility:hidden;
  transition:opacity .45s ease, transform .45s cubic-bezier(.2,.7,.3,1), visibility .45s; padding:18px 20px 16px; border-radius:16px;
  background:rgba(12,14,19,0.94); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.1), 0 30px 70px -20px rgba(0,0,0,0.95); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);}
.v3[data-mode="record"] .v3-log{opacity:1; visibility:visible; transform:translate(-50%,-50%) scale(1);}
.v3-log p{margin:0 0 10px; font-family:var(--mono); font-size:9.5px; letter-spacing:0.18em; text-transform:uppercase; color:var(--faint); display:flex; justify-content:space-between;}
.v3-log ol{list-style:none; margin:0; padding:0; font-family:var(--mono); font-size:11.5px; line-height:1.95; color:var(--muted);}
.v3-log li{display:flex; gap:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.v3-log li span{color:var(--faint);}
.v3-log .g{color:var(--green);} .v3-log .b{color:var(--accent2);} .v3-log .a{color:var(--amber);}
.v3-log footer{display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:12px; padding-top:12px; border-top:1px solid var(--line2);
  font-family:var(--mono); font-size:9.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--faint);}
.v3-log footer .vp{transform:rotate(-3deg);}

.v3-note{margin:14px auto 0; max-width:1180px; padding:0 var(--pad); font-family:var(--mono); font-size:10px; letter-spacing:0.14em; text-transform:uppercase; color:var(--dim); text-align:center;}

/* the card row filled in when a room is tapped */
.v3 .vrow[data-ly="room"] .vc-name b{min-height:1em;}

/* narrower tablets drop chrome first, the same order as the 2D view */
@container (max-width:760px){ .v3-map{height:min(75cqw, max(380px, calc(100svh - 320px)));} .v3-log{width:calc(100% - 110px);} }
@container (max-width:520px){
  .v3-map{height:min(100cqw, max(320px, calc(100svh - 300px)));}
  .v3-lock{display:none;}
  .v3 .vos-top, .v3 .vos-basis, .v3 .vos-lvl, .v3 .vos-toast, .v3 .vos-log, .v3 .vos-end{display:none;}
  .v3-ctl{top:auto; bottom:10px; right:10px; transform:none; grid-auto-flow:column;}
  .v3-ctl button{width:34px; height:32px;}
  .v3-ctl .zi, .v3-ctl .zo{display:none;}
  .v3-hint{left:10px; bottom:12px; font-size:8.5px;}
  .v3-tour{display:none;}
  .v3-chip{font-size:8.5px; letter-spacing:0.08em; padding:4px 7px 3px; gap:4px;}
  .v3-chip i{width:5px; height:5px;}
  .v3-chip.two{padding:7px 9px;} .v3-chip.two .m{width:84px;}
  .v3-chip.big b{font-size:13px;}
  .v3-log{width:calc(100% - 28px); padding:14px 14px 12px;} .v3-log ol{font-size:10.5px; line-height:1.85;}
  .v3-side{width:19px; height:19px; font-size:9.5px;}
}
@media (max-width:900px){ .v3-stage{perspective:1200px;} }
@media (prefers-reduced-motion:reduce){ .v3-tilt{transform:none !important;} .v3-chip.grn i{animation:none;} }
/* the readings in words, for screen readers */
.v3-sr{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;}
/* until the model draws, and when it cannot, the map controls stay out of the way */
.v3:not(.ready) .v3-ctl, .v3:not(.ready) .v3-hint, .v3:not(.ready):not(.flat) .v3-tour{opacity:0; pointer-events:none;}
