/* app.css — the chrome around the drawing.
   Type in rem so the reader's text-size preference is honoured, not just zoom
   (Doctrine §4). No fixed size that ignores the space available: panels are
   capped against the viewport at the moment they open, and anything that
   cannot fit scrolls inside itself with its dismiss control always reachable.
   Meaning never rides on hue: state is carried by text, shape and weight. */

:root{
  --bg:#0B1020; --bg2:#0E1428; --surface:#151B30; --surface-hi:#1B2340;
  --line:#26304F; --text:#EAECF5; --muted:#8B93AD;
  --amber:#F2A65A; --magenta:#E0619E; --cyan:#58C6E0; --slate:#8A97FF;
  --danger:#E0619E;
  --chrome: 0.9375rem;
}
@media (prefers-color-scheme:light){
  :root{
    --bg:#F4F6FB; --bg2:#FBFCFE; --surface:#FFFFFF; --surface-hi:#F0F3FA;
    --line:#D5DCEA; --text:#171C2B; --muted:#586079;
    --amber:#B45309; --magenta:#B03270; --cyan:#0E6E88; --slate:#4A54C8;
    --danger:#B03270;
  }
}

*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--bg);
  color:var(--text);
  font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
  overflow:hidden;
  touch-action:none;
}

.app{display:flex;flex-direction:column;height:100dvh}

/* ---- toolbar ---------------------------------------------------------- */
.bar{
  display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;
  padding:.375rem .5rem;
  background:var(--bg2);border-bottom:1px solid var(--line);
  flex:0 0 auto;
}
.bar-group{display:flex;align-items:center;gap:.25rem}
.bar-group + .bar-group{
  margin-left:.25rem;padding-left:.5rem;border-left:1px solid var(--line);
}
.spacer{flex:1 1 auto;min-width:0}

button,select,input[type="number"],input[type="text"]{font:inherit;font-size:var(--chrome)}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.375rem;
  min-height:2.75rem;min-width:2.75rem;padding:0 .625rem;
  background:var(--surface);color:var(--text);
  border:1px solid var(--line);border-radius:.625rem;
  cursor:pointer;white-space:nowrap;
}
.btn:hover{background:var(--surface-hi)}
.btn:focus-visible{outline:2px solid var(--slate);outline-offset:2px}
.btn[disabled]{opacity:.45;cursor:default}
/* Selected state is a filled chip WITH a tick — the accepted filter-chip
   pattern (hub LESSONS 6), never hue alone. */
.btn[aria-pressed="true"]{background:var(--slate);border-color:var(--slate);color:var(--bg)}
.btn[aria-pressed="true"]::before{content:"✓ ";font-weight:700}
.btn.danger{border-color:var(--danger);color:var(--danger)}

/* The build stamp. A real colour token, never opacity: an opacity is invisible
   to a contrast gate, which is how two sibling apps shipped a stamp that
   measured 2.54:1 while the gate read 4.79:1 (hub LESSONS §8). */
.build{
  font-size:0.75rem;
  font-variant-numeric:tabular-nums;
  color:var(--muted);
  letter-spacing:0.02em;
  align-self:center;
  margin-left:-4px;
}

.title{
  font-size:.8125rem;font-weight:700;letter-spacing:.02em;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* ---- stage ------------------------------------------------------------ */
.stage{position:relative;flex:1 1 auto;min-height:0;overflow:hidden}
canvas{display:block;width:100%;height:100%;touch-action:none}

/* Standing mode indicator with an obvious exit (Doctrine §3). */
.mode-flag{
  position:absolute;left:50%;transform:translateX(-50%);top:.5rem;
  display:none;align-items:center;gap:.5rem;
  padding:.25rem .25rem .25rem .75rem;
  background:var(--surface);border:2px solid var(--slate);border-radius:999px;
  font-size:.8125rem;font-weight:650;max-width:calc(100% - 1rem);
}
.mode-flag[data-on="true"]{display:flex}
.mode-flag span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Off-canvas VP markers: real buttons, so they are tabbable and labelled. */
.vp-marker{
  position:absolute;transform:translate(-50%,-50%);
  min-height:2.75rem;min-width:2.75rem;padding:0 .5rem;
  display:inline-flex;align-items:center;justify-content:center;gap:.25rem;
  background:var(--surface);color:var(--text);
  border:2px solid var(--slate);border-radius:999px;
  font-size:.75rem;font-weight:700;cursor:grab;
}
.vp-marker:focus-visible{outline:2px solid var(--slate);outline-offset:2px}
.vp-marker[data-locked="true"]{border-style:dashed;color:var(--muted)}

.toast{
  position:absolute;left:50%;transform:translateX(-50%);bottom:.75rem;
  max-width:min(30rem,calc(100% - 1.5rem));
  padding:.625rem .875rem;border-radius:.75rem;
  background:var(--surface);border:1px solid var(--line);
  font-size:.875rem;line-height:1.45;
  display:none;
}
.toast[data-on="true"]{display:block}
.toast[data-kind="error"]{border-color:var(--danger)}

/* ---- side panel ------------------------------------------------------- */
.panel{
  position:absolute;right:.5rem;top:.5rem;
  width:min(20rem,calc(100% - 1rem));
  /* measured against the space it has AT THE MOMENT IT OPENS, never a constant,
     and the floor never exceeds the container (Doctrine §4) */
  max-height:calc(100% - 1rem);
  display:none;flex-direction:column;
  background:var(--surface);border:1px solid var(--line);border-radius:.875rem;
  overflow:hidden;
}
.panel[data-on="true"]{display:flex}
.panel-head{
  display:flex;align-items:center;gap:.5rem;
  padding:.375rem .375rem .375rem .75rem;
  border-bottom:1px solid var(--line);flex:0 0 auto;
}
.panel-head h2{font-size:.9375rem;margin:0;flex:1 1 auto}
.panel-body{padding:.5rem;overflow:auto;flex:1 1 auto;min-height:0}

.vp-row{
  display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;
  padding:.375rem;border:1px solid var(--line);border-radius:.625rem;
  margin-bottom:.375rem;
}
.vp-row[data-active="true"]{border-color:var(--slate);border-width:2px}
.vp-name{
  flex:1 1 6rem;min-width:0;font-weight:650;font-size:.875rem;
  display:flex;align-items:center;min-height:2.75rem;
}
.coord{display:flex;align-items:center;gap:.25rem;font-size:.8125rem;color:var(--muted)}
.coord input{
  width:5rem;min-height:2.75rem;padding:0 .5rem;
  background:var(--bg2);color:var(--text);
  border:1px solid var(--line);border-radius:.5rem;
}
.coord input:focus-visible{outline:2px solid var(--slate);outline-offset:1px}
.hint{font-size:.8125rem;color:var(--muted);line-height:1.5;margin:.25rem 0 .5rem}
.empty{font-size:.875rem;color:var(--muted);line-height:1.5}

/* ---- dialogs ---------------------------------------------------------- */
dialog{
  width:min(30rem,calc(100vw - 1.5rem));
  max-height:calc(100dvh - 1.5rem);
  padding:0;color:var(--text);background:var(--surface);
  border:1px solid var(--line);border-radius:.875rem;
  overflow:hidden;
}
dialog::backdrop{background:rgba(4,7,18,.62)}
.dlg{display:flex;flex-direction:column;max-height:calc(100dvh - 1.5rem)}
.dlg-head{
  display:flex;align-items:center;gap:.5rem;
  padding:.375rem .375rem .375rem .875rem;
  border-bottom:1px solid var(--line);flex:0 0 auto;
}
.dlg-head h2{font-size:1rem;margin:0;flex:1 1 auto}
.dlg-body{padding:.875rem;overflow:auto;flex:1 1 auto;min-height:0;font-size:.9375rem;line-height:1.55}
/* The way out is pinned, so a long body can never bury it (hub LESSONS). */
.dlg-foot{
  display:flex;flex-wrap:wrap;gap:.375rem;justify-content:flex-end;
  padding:.5rem .875rem;border-top:1px solid var(--line);flex:0 0 auto;
  background:var(--surface);
}
.field{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin-bottom:.75rem}
.field label{flex:1 1 9rem;min-width:0}
.field input[type="number"],.field input[type="text"],.field select{
  flex:0 1 8rem;min-height:2.75rem;padding:0 .5rem;
  background:var(--bg2);color:var(--text);
  border:1px solid var(--line);border-radius:.5rem;
}
.field input:focus-visible,.field select:focus-visible{outline:2px solid var(--slate);outline-offset:1px}
.check{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}
.check input{width:1.25rem;height:1.25rem}
.dlg-body h3{font-size:.9375rem;margin:1rem 0 .375rem}
.dlg-body p{margin:.5rem 0}
.dlg-body a{color:var(--slate)}
.dlg-body ul{margin:.5rem 0;padding-left:1.25rem}
.dlg-body li{margin:.25rem 0}
.proj-row{
  display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;
  padding:.375rem;border:1px solid var(--line);border-radius:.625rem;margin-bottom:.375rem;
}
.proj-row .nm{flex:1 1 8rem;min-width:0;display:flex;align-items:center;min-height:2.75rem}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

@media (prefers-contrast:more){
  :root{--line:#3D4A72;--muted:#AEB6CE}
  @media (prefers-color-scheme:light){:root{--line:#9AA6C2;--muted:#3D445C}}
  .btn,.panel,.vp-row,dialog{border-width:2px}
}
@media (forced-colors:active){
  .btn,.panel,.vp-row,dialog,.vp-marker{border:1px solid CanvasText}
  .btn:focus-visible,.vp-marker:focus-visible{outline:2px solid Highlight}
  .btn[aria-pressed="true"]{background:Highlight;color:HighlightText}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none !important;animation:none !important}
}
