/* ============================================================
   LIGHT GLASS TOKENS (single theme)
   ============================================================ */
.wf-nav{
  --surface:rgba(255,255,255,.56);
  --sticky-bg:#F2F3F2;
  --substuck-bg:#F7F8F8;
  --border:rgba(255,255,255,.70);
  --divider:rgba(70,92,80,.16);
  --label:#41584C;
  --label-hover:#27543C;
  --header-hover:rgba(56,120,90,.09);
  --text:#1F2D26;
  --icon:#3C5247;
  --icon-hover:#2F6B4D;
  --muted:#6E8077;
  --row-hover:rgba(60,74,67,.06);
  --active-bg:rgba(255,255,255,.40);
  --active-text:#235446;
  --accent:#5C9A7E;
  --accent-line:rgba(92,154,126,.45);   /* organic border tint */
  --dot-green:#4FA37C;
  --dot-orange:#E8C08A;                  /* paler, less shouty */
  --dot-black:#2B332E;                   /* failed = calm near-black */
  --dot-gray:#A7B0AA;                    /* not started yet */
  --search-bd-focus:rgba(255,255,255,.95);
  --search-bg-focus:rgba(255,255,255,.50);
  --focus:rgba(60,120,92,.55);
  --tooltip-bg:rgba(24,40,32,.94);
  --tooltip-fg:#FFFFFF;
  --scroll-thumb:rgba(90,112,100,.30);
  --blur:blur(20px) saturate(180%) brightness(1.03);
  --shadow:inset 0 1px 0 rgba(255,255,255,.6), 0 10px 30px rgba(55,72,64,.14);
  --radius:9px;
  --radius-lg:16px;
  --ease:cubic-bezier(.32,.72,0,1);   /* unified motion curve */
  --dur:.24s;
  --dur-rev:.42s;                     /* reveal (expand/collapse) */
}

/* AirWanderer integration note:
   The original sidebar-nav demo file shipped a ``body`` block here
   (margin / display:flex / padding / demo background). It was the
   stand-alone demo page styling and per IMPLEMENTATION.md §2.1 must
   be removed when embedding. The AirWanderer body is laid out by
   ``.app`` (CSS grid in main.css) and must keep its existing rules.
   The shell coordination rule that places .wf-nav into the .app grid
   lives in saas-shell.css under the Slice 4E-1 integration block. */

/* ============================================================
   COMPONENT
   ============================================================ */
.wf-nav,.wf-nav *{box-sizing:border-box}
.wf-nav{
  position:relative;
  width:240px;background-color:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:13px 11px;font-family:inherit;color:var(--text);user-select:none;
  display:flex;flex-direction:column;max-height:calc(100vh - 110px);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:var(--shadow);
  transition:width var(--dur) var(--ease),padding var(--dur) var(--ease),
             height var(--dur) var(--ease),transform var(--dur) var(--ease),
             max-height var(--dur-rev) var(--ease);
  will-change:width,height,transform;
  animation:wf-nav-in .55s var(--ease) backwards;
}
@keyframes wf-nav-in{
  from{opacity:0;transform:translateY(9px) scale(.984)}
  to{opacity:1;transform:none}
}
/* gentle staggered settle for the top-level blocks.
   fill is `backwards` (not `both`) so once the intro finishes the
   elements obey normal transitions again — otherwise the filled
   animation would pin their opacity and the collapse fade would
   skip Search / New workflow, making the exit feel broken. */
.wf-nav__head,.wf-search,.wf-cta{
  animation:wf-row-in .55s var(--ease) backwards}
.wf-scroll>*{animation:wf-fade-in .55s var(--ease) backwards}
.wf-search{animation-delay:.06s}
.wf-cta{animation-delay:.11s}
.wf-scroll>*:nth-child(1){animation-delay:.15s}
.wf-scroll>*:nth-child(2){animation-delay:.20s}
.wf-scroll>*:nth-child(3){animation-delay:.25s}
.wf-scroll>*:nth-child(4){animation-delay:.30s}
.wf-scroll>*:nth-child(n+5){animation-delay:.34s}
@keyframes wf-row-in{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:none}
}
@keyframes wf-fade-in{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .wf-nav,.wf-nav__head,.wf-search,.wf-cta,.wf-scroll>*{animation:none}
  .wf-group__body,.wf-blocks,.wf-model__panel{transition:none}
}

.wf-nav__top{display:flex;flex-direction:column;flex:none}
.wf-nav__sub{display:flex;flex-direction:column;overflow:hidden;
  max-height:150px;opacity:1;
  transition:max-height var(--dur-rev) var(--ease),
             opacity .2s var(--ease)}
.wf-nav.is-topcollapsed .wf-nav__sub{
  max-height:0;opacity:0;pointer-events:none}
.wf-nav.is-topcollapsed .wf-nav__head{padding-bottom:4px}
.wf-nav.is-topcollapsed .wf-scroll{margin-top:0}
/* re-fitting the docked nav must be instantaneous — otherwise the
   0.42s max-height curve animates toward the transient measuring
   value and snaps back, which looks like the layout shaking */
.wf-nav.is-navmeasure{transition:none!important}
.wf-limitpanel.is-railhidden{display:none!important}
.wf-limitpanel.is-docked.is-dockappear{
  animation:wf-lim-in .26s var(--ease) both}
.wf-nav__head{
  display:flex;align-items:center;justify-content:space-between;
  padding:2px 1px 13px 6px;color:var(--label);
  font-size:11px;letter-spacing:.07em;font-weight:500;text-transform:uppercase;
  transition:padding .24s var(--ease);
}
.wf-nav__title{white-space:nowrap;overflow:hidden}
.wf-nav__tools{display:flex;align-items:center;flex:none}
.wf-nav__tools>.wf-iconbtn{margin-left:2px}
.wf-nav__tools>.wf-iconbtn:first-child{margin-left:0}
.wf-iconbtn{
  display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;border:0;background:transparent;color:var(--muted);
  border-radius:8px;cursor:pointer;flex:none;transition:background .12s,color .12s;
}
.wf-iconbtn:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-iconbtn svg{width:18px;height:18px;display:block}
.wf-nav__pin svg{width:18px;height:18px}
.wf-nav__pin[aria-pressed="true"]{color:var(--accent);background:var(--row-hover)}
.wf-nav__pin[aria-pressed="true"] svg path{fill:currentColor;
  fill-opacity:.16;stroke:currentColor}
.wf-nav__collapse .ic-rail{display:none}
.wf-nav.is-rail .wf-nav__collapse .ic-expanded{display:none}
.wf-nav.is-rail .wf-nav__collapse .ic-rail{display:block}

/* resize handle — sits just OUTSIDE the bottom-right corner with
   a small margin. Hovering the corner area reveals a resize icon
   and lets the user drag to change width AND height. */
.wf-grip{
  position:absolute;right:-26px;bottom:-26px;width:34px;height:34px;
  border:0;background:transparent;padding:0;cursor:default;
  z-index:7;touch-action:none;color:var(--muted);
  display:flex;align-items:center;justify-content:center}
.wf-grip__ico{
  display:flex;align-items:center;justify-content:center;width:16px;height:16px;
  opacity:0;transform:scale(.55);transform-origin:center;
  transition:opacity .18s var(--ease),transform .18s var(--ease)}
.wf-grip__ico svg{width:16px;height:16px;display:block}
.wf-grip:hover .wf-grip__ico,
.wf-nav.is-resizing .wf-grip__ico{opacity:.85;transform:scale(1)}
.wf-nav.is-resizing .wf-grip{color:var(--accent)}
.wf-nav.is-rail .wf-grip,.wf-nav.is-stats .wf-grip,
.wf-nav.is-pages .wf-grip{display:none}
.wf-nav.is-rail .wf-nav__pin,
.wf-nav.is-rail .wf-nav__drag,
.wf-nav.is-rail .wf-nav__reset{display:none}
/* The header tools (drag / pin / reset) rest HIDDEN and only
   appear while the header is hovered or keyboard-focused. The
   collapse uses the same sequenced motion as Pages: the glyph
   fades + scales away first, then the transparent box collapses
   its width — and the reverse when revealing. */
.wf-nav__tools>.wf-nav__drag,
.wf-nav__tools>.wf-nav__pin,
.wf-nav__tools>.wf-nav__reset{
  overflow:hidden;
  width:0;opacity:0;margin:0;pointer-events:none;
  transform:translateX(-7px) scale(.78);
  transition:background .12s,color .12s,
             opacity .26s var(--ease),
             transform .26s var(--ease),
             width .30s var(--ease) .18s,
             margin .30s var(--ease) .18s}
/* revealed: header hovered / focused — drag + pin */
.wf-nav.is-headhover .wf-nav__drag,
.wf-nav.is-headhover .wf-nav__pin{
  width:30px;opacity:1;margin-left:2px;pointer-events:auto;
  transform:none;
  transition:background .12s,color .12s,
             width .30s var(--ease),margin .30s var(--ease),
             opacity .26s var(--ease) .16s,
             transform .26s var(--ease) .16s}
/* pinned size — pin stays visible even without the hover */
.wf-nav.is-pinned .wf-nav__pin{
  width:30px;opacity:1;margin-left:2px;pointer-events:auto;
  transform:none;
  transition:background .12s,color .12s,
             width .30s var(--ease),margin .30s var(--ease),
             opacity .26s var(--ease) .16s,
             transform .26s var(--ease) .16s}
/* reset only matters once the panel has been moved */
.wf-nav.is-headhover.is-moved .wf-nav__reset{
  width:30px;opacity:1;pointer-events:auto;transform:none;
  transition:background .12s,color .12s,
             width .30s var(--ease),margin .30s var(--ease),
             opacity .26s var(--ease) .16s,
             transform .26s var(--ease) .16s}
/* the top toggle for the search / new-workflow strip — exists
   only in Pages mode. display:none when absent (zero footprint);
   eases in softly when Pages becomes active. */
.wf-nav__topx{display:none}
.wf-nav.is-pages .wf-nav__topx{
  display:flex;animation:wf-topx-in .3s var(--ease) both}
.wf-nav.is-rail .wf-nav__topx{display:none}
@keyframes wf-topx-in{
  from{opacity:0;transform:translateX(-7px) scale(.78)}
  to{opacity:1;transform:none}}
/* legible toggle state without an arrow: the bars mark
   lights up (accent) while the strip is open, muted while hidden */
.wf-nav__topx{transition:background .14s,color .14s}
.wf-nav.is-pages:not(.is-topcollapsed) .wf-nav__topx{
  color:var(--accent);background:var(--row-hover)}
.wf-nav__drag{cursor:grab}
/* Pages mode hides drag / pin / reset regardless of hover or
   pin — placed last so it overrides every reveal rule above */
.wf-nav.is-pages .wf-nav__drag,
.wf-nav.is-pages .wf-nav__pin,
.wf-nav.is-pages.is-moved .wf-nav__reset,
.wf-nav.is-pages .wf-nav__reset{
  width:0;opacity:0;margin:0;pointer-events:none;
  transform:translateX(-7px) scale(.78);
  transition:background .12s,color .12s,
             opacity .26s var(--ease),
             transform .26s var(--ease),
             width .30s var(--ease) .18s,
             margin .30s var(--ease) .18s}
.wf-nav.is-dragging{transition:none;will-change:transform}
/* pinned size must never leak into the collapsed rail look */
.wf-nav.is-rail{width:52px!important}
/* no transitions while actively dragging the size */
.wf-nav.is-resizing{transition:none}
/* smoother menu exit: fade contents out/in around the collapse */
.wf-nav.is-railing .wf-nav__title,
.wf-nav.is-railing .wf-search,
.wf-nav.is-railing .wf-cta,
.wf-nav.is-railing .wf-scroll,
.wf-nav.is-railing .wf-stats{
  opacity:0;transition:opacity .19s var(--ease)}
/* ---- ROUND 29: the rail motion. One duration and one curve for the box (width, height,
   padding, radius, transform), both directions; the stylesheet owns it. The nav's transition on
   the workflow route is otherwise `top, left` only (topbar.css), which is why the expand used to
   snap. `.app > ` outranks that rule; `.is-navmeasure` (transition:none!important) and
   `.is-reduced` (.001ms!important) still outrank this one. ---- */
.wf-nav{--dur-rail:var(--aw-chrome-dur, .32s)}   /* ROUND 30: the chrome's one clock */
.wf-nav.is-reduced{--dur-rail:.001ms}
/* measuring the settled rail box: nothing in it may be mid-transition (the head's padding
   transition alone made the old measurement 57 instead of 42, and the last 15 px snapped) */
.wf-nav.is-railmeasure,.wf-nav.is-railmeasure *{transition:none!important}
/* (0,6,1): above topbar.css's `body.route-workflow .app > .wf-nav` (0,3,1), whose `top, left,
   translate` list would otherwise replace this one; the :not()s hand the measuring and dragging
   classes' `transition:none!important` their turn */
body .app > .wf-nav.is-railmotion:not(.is-navmeasure):not(.is-railmeasure):not(.is-dragging),
.wf-nav.is-railmotion:not(.is-navmeasure):not(.is-railmeasure):not(.is-dragging){
  overflow:hidden;
  transition:width var(--dur-rail) var(--ease),height var(--dur-rail) var(--ease),
             padding var(--dur-rail) var(--ease),transform var(--dur-rail) var(--ease),
             border-radius var(--dur-rail) var(--ease),background-color var(--dur-rail) var(--ease),
             border-color var(--dur-rail) var(--ease),box-shadow var(--dur-rail) var(--ease),
             translate var(--dur-rail) var(--ease),
             top var(--aw-chrome-dur) var(--aw-chrome-ease),left .42s var(--ease)}
/* the content stays in the layout while the box moves (the rail's display:none applies when
   the motion is over) and fades: out over the first part of a collapse, in over the last part
   of an expand */
.wf-nav.is-rail.is-railmotion .wf-nav__title{display:inline}
.wf-nav.is-rail.is-railmotion .wf-search,
.wf-nav.is-rail.is-railmotion .wf-cta,
.wf-nav.is-rail.is-railmotion .wf-side{display:flex}
.wf-nav.is-rail.is-railmotion .wf-scroll{display:block}
.wf-nav.is-railmotion .wf-side{opacity:0;transition:opacity .12s var(--ease)}
.wf-nav.is-rail.is-railmotion .wf-nav__title,
.wf-nav.is-rail.is-railmotion .wf-search,
.wf-nav.is-rail.is-railmotion .wf-cta,
.wf-nav.is-rail.is-railmotion .wf-scroll{opacity:0;transition:opacity .14s var(--ease)}
.wf-nav.is-railmotion:not(.is-rail) .wf-nav__title,
.wf-nav.is-railmotion:not(.is-rail) .wf-search,
.wf-nav.is-railmotion:not(.is-rail) .wf-cta,
.wf-nav.is-railmotion:not(.is-rail) .wf-scroll{transition:opacity .18s var(--ease) .12s}
/* the head: the title takes the slack so the collapse button rides the box's right edge and
   ends centred in the rail exactly where the rail rules put it; the hover-revealed drag / pin /
   reset buttons are out of the row for the whole motion (they would sit in a 40 px box) */
.wf-nav.is-railmotion .wf-nav__title{flex:1 1 0;min-width:0}
.wf-nav.is-railmotion .wf-nav__head{transition:padding var(--dur-rail) var(--ease)}
.wf-nav.is-railmotion .wf-nav__tools>.wf-nav__drag,
.wf-nav.is-railmotion .wf-nav__tools>.wf-nav__pin,
.wf-nav.is-railmotion .wf-nav__tools>.wf-nav__reset{
  width:0!important;opacity:0!important;margin:0!important;transition:none!important}
.wf-nav.is-railmotion .wf-nav__tools .wf-iconbtn.wf-nav__collapse{
  transition:width var(--dur-rail) var(--ease),height var(--dur-rail) var(--ease),
             border-radius var(--dur-rail) var(--ease),background-color .12s,color .12s}

.wf-search{
  display:flex;align-items:center;gap:8px;padding:0 11px;height:35px;
  border:1px solid var(--border);border-radius:var(--radius);
  color:var(--muted);margin-bottom:8px;flex:none;background:transparent;
  transition:border-color .14s ease,background-color .14s ease;
}
.wf-search:focus-within{border-color:var(--search-bd-focus);background:var(--search-bg-focus)}
.wf-search svg{flex:none;width:16px;height:16px}
.wf-search input{flex:1;min-width:0;border:0;outline:0;background:transparent;
  font:inherit;font-size:13px;color:var(--text)}
.wf-search input::placeholder{color:var(--muted)}
.wf-search__clear{display:none;border:0;background:transparent;color:var(--muted);
  cursor:pointer;padding:2px;border-radius:5px;line-height:0}
.wf-search__clear:hover{color:var(--label-hover);background:var(--row-hover)}
.wf-search__clear svg{width:14px;height:14px}
.wf-search.has-text .wf-search__clear{display:flex}

.wf-scroll{overflow-y:auto;overflow-x:hidden;margin:8px -11px 0;padding:0 11px;
  flex:1;min-height:0;scrollbar-width:none;-ms-overflow-style:none}
.wf-scroll::-webkit-scrollbar{width:0;height:0;display:none}

/* custom scroll thumb — lives in the panel, not in the scroll
   box, so the stacked header can span the full width. Its track
   begins BELOW the pinned header (offset set from JS). */
.wf-sb{position:absolute;right:3px;width:4px;border-radius:4px;
  background:var(--scroll-thumb);opacity:0;pointer-events:none;
  transition:opacity .25s var(--ease);z-index:5}
.wf-nav:hover .wf-sb.is-on,.wf-nav.is-scrolling .wf-sb.is-on{opacity:1}
.wf-nav.is-rail .wf-sb,.wf-nav.is-stats .wf-sb{display:none}
.wf-divider{border-top:1px solid var(--divider);margin:7px 5px}
.wf-nav.is-searching .wf-divider,
.wf-nav.is-searching .wf-plan-sec{display:none}
/* Tools is workflow-scoped — Inspector / Execution / Environment all
   act on the currently-open workflow, so the section appears exactly
   on workflow routes and is hidden on Pages routes.
   AirWanderer integration (Slice 4E-7E fix-pass): the original gate
   was .wf-nav.has-wfctx, but the host suppresses .has-wfctx via
   nav._airwandererSuppressHasWfctx to keep .wf-side anchored at
   top:0 on workflow routes (the new shell layout aligns chips with
   the canvas-toolbar row; flipping has-wfctx on would push them to
   top:15px). The .has-wfctx semantics is therefore now "side-chip
   anchor only"; Tools visibility moves to body.route-workflow,
   which is exactly true when a workflow is open. */
body:not(.route-workflow) .wf-nav .wf-group[data-id="tools"],
body:not(.route-workflow) .wf-nav .wf-divider:has(+ .wf-group[data-id="tools"]){
  display:none}
/* …and when it does appear, let it ease in quietly rather than
   snap. The section uses opacity only (a transform here would
   break its sticky header); the thin divider gets a small slide. */
@keyframes wf-tools-fade{from{opacity:0}to{opacity:1}}
@keyframes wf-tools-in{
  from{opacity:0;transform:translateY(-7px)}
  to{opacity:1;transform:none}}
body.route-workflow .wf-nav .wf-group[data-id="tools"]{
  animation:wf-tools-fade .46s var(--ease) both}
body.route-workflow .wf-nav .wf-divider:has(+ .wf-group[data-id="tools"]){
  animation:wf-tools-in .42s var(--ease) .03s both}
.wf-empty{padding:20px 12px;text-align:center;
  color:var(--muted);font-size:12.5px;letter-spacing:.01em}

/* ---- ROW ---- */
.wf-item{display:flex;align-items:center;width:100%;position:relative;
  border-radius:var(--radius);transition:background .12s}
.wf-item:hover{background:var(--row-hover)}
.wf-item.is-active,.wf-item.is-active:hover{background:var(--active-bg)}
.wf-item__btn{
  display:flex;align-items:center;gap:12px;flex:1;min-width:0;min-height:36px;
  border:0;background:transparent;cursor:pointer;text-align:left;
  padding:8px 11px;border-radius:var(--radius);color:var(--text);font:inherit;font-size:13px;
}
.wf-item__icon{width:18px;height:18px;flex:none;color:var(--icon);line-height:0;
  display:flex;align-items:center;justify-content:center;transition:color .12s}
.wf-item__icon svg{width:18px;height:18px;display:block}
.wf-item:hover .wf-item__icon{color:var(--icon-hover)}
.wf-item__label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  flex:1;min-width:0}
.wf-item__label[contenteditable="true"]{outline:0;border-radius:4px;
  box-shadow:0 0 0 2px var(--accent);background:var(--surface);padding:0 4px;margin:0 -4px}

.wf-item.is-active .wf-item__btn{color:var(--active-text);font-weight:500}
.wf-item.is-active .wf-item__icon{color:var(--active-text)}
.wf-item__bar{position:absolute;left:4px;top:7px;bottom:7px;width:2px;border-radius:2px;
  background:var(--accent);opacity:0;transform:scaleY(.4);transform-origin:center;
  transition:opacity .15s,transform .15s}
.wf-item.is-active .wf-item__bar{opacity:1;transform:scaleY(1)}

.wf-item__mark{display:flex;align-items:center;justify-content:center;
  width:18px;height:18px}
.wf-item__mark svg{width:14px;height:14px;display:block}
.wf-item__mark.green{color:var(--dot-green)}
.wf-item__mark.orange{color:var(--dot-orange)}
.wf-item__mark.black{color:var(--dot-black)}
.wf-item__mark.gray{color:var(--dot-gray)}

.wf-item.is-cta .wf-item__icon{color:var(--accent)}
.wf-item.is-cta:hover .wf-item__icon{color:var(--icon-hover)}
.wf-item.is-hidden{display:none}
/* Audit fix: hide the block/child tree that trails a search-hidden
   row. Without this, a non-matching project row disappeared but its
   expanded .wf-blocks sibling stayed visible (`.is-open + .wf-blocks`
   still matches a display:none sibling), leaving orphan child rows
   floating in the group. Mirrors the .wf-recent :has() guard. */
.wf-item.is-hidden + .wf-blocks{display:none}

/* nested blocks — simple, calm marker */
.wf-blocks{display:grid;grid-template-rows:0fr;
  grid-template-columns:minmax(0,1fr);
  transition:grid-template-rows var(--dur-rev) var(--ease)}
.wf-item.is-open + .wf-blocks{grid-template-rows:1fr}
.wf-blocks__inner{overflow:hidden;overflow:clip;min-height:0;min-width:0}
.wf-block .wf-item__btn{padding-left:42px;min-height:32px;font-size:12.5px}
/* blocks that live under a workflow inside a Project sit one
   level deeper than that workflow row */
.wf-blocks--deep .wf-block .wf-item__btn{padding-left:60px}
.wf-block .wf-item__icon{width:14px;height:14px;color:var(--muted)}
.wf-block .wf-item__icon svg{width:14px;height:14px}
.wf-block:hover .wf-item__icon{color:var(--icon-hover)}
.wf-block.is-active .wf-item__icon{color:var(--active-text)}

/* ---- SECTION HEADER (tab) ---- */
.wf-group__head{display:flex;align-items:center;width:100%;
  border-radius:var(--radius);transition:background .12s}
.wf-group__head:hover{background:var(--header-hover)}
/* sticky: headers pin to the top of the scroll area. At rest a
   header has NO backing (clean, no white hint). The .is-stuck
   class is added by JS only while the header is actually pinned
   during scroll — only then does it get the frosted backing so
   rows underneath don't show through. */
.wf-scroll .wf-group__head{position:sticky;top:0;z-index:3;
  transition:background .12s}
.wf-scroll .wf-group__head.is-stuck{
  background-color:var(--sticky-bg);border-radius:0;transition:none;
  width:calc(100% + 22px);
  margin-left:-11px;margin-right:-11px;padding-left:11px;padding-right:11px}
.wf-scroll .wf-group__head.is-stuck:hover{
  background-color:var(--sticky-bg);
  background-image:linear-gradient(var(--header-hover),var(--header-hover))}
.wf-group__toggle{
  display:flex;align-items:center;flex:1;min-width:0;
  border:0;background:transparent;cursor:pointer;padding:8px 7px;color:var(--label);
  font:inherit;font-size:11px;letter-spacing:.06em;font-weight:500;
  text-transform:uppercase;transition:color .12s;
}
.wf-group__toggle span:first-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-group__head:hover .wf-group__toggle{color:var(--label-hover)}
.wf-group__exp{display:flex;align-items:center;justify-content:center;flex:none;
  border:0;background:transparent;cursor:pointer;padding:8px 7px 8px 3px;
  color:var(--muted)}
.wf-group__chev{color:inherit;transition:transform var(--dur) var(--ease),color .12s;
  flex:none;line-height:0}
.wf-group__head:hover .wf-group__chev{color:var(--label-hover)}
.wf-group__chev svg{width:14px;height:14px;display:block}
.wf-group[aria-collapsed="true"] .wf-group__chev{transform:rotate(-90deg)}
.wf-group__body{display:grid;grid-template-rows:1fr;
  grid-template-columns:minmax(0,1fr);
  transition:grid-template-rows var(--dur-rev) var(--ease)}
.wf-group[aria-collapsed="true"] .wf-group__body{grid-template-rows:0fr}
.wf-group__inner{overflow:hidden;overflow:visible clip;min-height:0;min-width:0}
.wf-group.is-empty{display:none}

/* ---- ACTION ICONS — base (headers + non-recent items) ----
   Collapse to 0 width; reveal on hover so labels keep full width. */
.wf-act,.wf-nav .wf-hint,.wf-edit,.wf-add{   /* ROUND 39: .wf-hint scoped - the inspector has a paragraph of the same name */
  display:flex;align-items:center;justify-content:center;
  width:0;height:24px;flex:none;border:0;background:transparent;color:var(--muted);
  border-radius:50%;cursor:pointer;opacity:0;pointer-events:none;overflow:hidden;
  transition:width var(--dur) var(--ease),margin var(--dur) var(--ease),
             opacity .14s,color .12s,background .12s;
}
.wf-act svg,.wf-nav .wf-hint svg,.wf-edit svg,.wf-add svg{width:14px;height:14px;display:block}
.wf-nav .wf-hint{cursor:help}
.wf-group__head:hover .wf-add,.wf-add:focus-visible{
  width:24px;opacity:.55;pointer-events:auto;margin-right:3px}
.wf-group__head:hover .wf-add:hover,.wf-add:focus-visible{
  opacity:1;color:var(--label-hover);background:var(--row-hover)}
.wf-item:not(.wf-item--recent):hover .wf-hint,
.wf-group__head:hover .wf-hint,
.wf-meter:hover .wf-hint,
.wf-nav .wf-hint:focus-visible{width:24px;opacity:.5;pointer-events:auto;margin-right:5px}
.wf-item:not(.wf-item--recent):hover .wf-hint:hover,
.wf-group__head:hover .wf-hint:hover,
.wf-meter:hover .wf-hint:hover,
.wf-hint:focus-visible{opacity:1;color:var(--label-hover);background:var(--row-hover)}

/* ---- RECENT WORKFLOW SUBSTACK ----
   Each recent row pins just below the pinned section header and
   hands off to the next as you scroll. The pinned row gets only
   a light, softly-frosted backing (not the solid header colour)
   so the header→workflow hierarchy stays readable. */
.wf-item--recent{position:sticky;top:var(--sub-top,33px);z-index:2}
/* when pinned, a full-bleed backing layer spans the whole menu
   width (like the section header) without shifting the row's
   own content. It sits behind the row's text/controls but above
   the scrolling content, regardless of scroll position. */
.wf-item--recent.is-substuck::before{
  content:"";position:absolute;top:0;bottom:0;left:-11px;right:-11px;
  background-color:var(--substuck-bg);z-index:-1}
.wf-item--recent.is-substuck:hover::before{
  background-image:linear-gradient(var(--row-hover),var(--row-hover))}
.wf-recent{position:relative;min-width:0}
.wf-recent:has(> .wf-item--recent.is-hidden){display:none}

/* project items: the row icon is a button to change it
   (nested workflow rows keep their status icon, untouched) */
.wf-group[data-id="projects"] .wf-item:not(.wf-block) .wf-item__icon{
  cursor:pointer;border-radius:6px;
  transition:background .12s,color .12s}
.wf-group[data-id="projects"] .wf-item:not(.wf-block) .wf-item__btn:hover .wf-item__icon{
  background:var(--row-hover)}
.wf-group[data-id="projects"] .wf-item:not(.wf-block) .wf-item__icon:hover{
  color:var(--icon-hover)}
.wf-cwf .wf-item__icon{width:18px;height:18px;color:inherit}
.wf-cwf .wf-item__mark svg{width:14px;height:14px}
/* the "Create new workflow" offer under an EMPTY project (round 13):
   the project-child row rhythm (.wf-block) with the CTA's accent plus
   glyph at the child row's 18px, not the block row's 14px */
.wf-newwf .wf-item__icon{width:18px;height:18px}
.wf-newwf .wf-item__icon svg{width:18px;height:18px}

/* icon picker popover */
.wf-iconpick{
  position:absolute;z-index:9;width:168px;padding:7px;
  display:grid;grid-template-columns:repeat(4,1fr);gap:3px;
  background:#FBFCFA;border:1px solid var(--border);
  border-radius:12px;box-shadow:0 12px 34px rgba(40,56,48,.20),
  0 0 0 1px rgba(60,74,67,.05);
  animation:wf-fade-in .14s var(--ease)}
.wf-iconpick__b{
  display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border:0;background:transparent;color:var(--muted);
  border-radius:8px;cursor:pointer;transition:background .12s,color .12s}
.wf-iconpick__b svg{width:18px;height:18px;display:block}
.wf-iconpick__b:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-iconpick__b.is-sel{color:var(--accent);background:var(--active-bg)}

/* project picker (list variant) */
.wf-iconpick.wf-pop{display:block;width:auto;min-width:188px;
  max-width:232px;padding:6px}
.wf-pop__h{font-size:11px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);padding:4px 8px 6px}
.wf-pop__b{display:flex;align-items:center;gap:9px;width:100%;
  padding:7px 8px;border:0;background:transparent;color:var(--text);
  border-radius:8px;cursor:pointer;font:inherit;font-size:13px;text-align:left;
  transition:background .12s,color .12s}
.wf-pop__b:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-pop__i{display:flex;align-items:center;justify-content:center;
  width:18px;height:18px;color:var(--muted);flex:none}
.wf-pop__i svg{width:16px;height:16px;display:block}
.wf-pop__t{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---- RECENT WORKFLOW: control region (zero reflow) ----
   The chevron stays at the row's right edge and only rotates on
   expand. Edit/stats and rename/delete/back float in as a small
   glass pill just left of it, so nothing in the row ever moves.
   Hidden groups are visibility:hidden — that removes the whole
   subtree from hit-testing, so an invisible group can never steal
   a click or hover from the visible one. */
.wf-racts{position:relative;flex:none;display:flex;align-items:center}
.wf-racts__cluster,.wf-racts .wf-editset{
  position:absolute;right:32px;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;gap:2px;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .14s,visibility 0s linear .14s}
.wf-racts .wf-act,.wf-racts .wf-edit{
  width:24px;opacity:1;overflow:visible;pointer-events:auto;
  transition:color .12s,background .12s}
.wf-hasacts:hover .wf-racts__cluster,
.wf-racts__cluster:focus-within{
  opacity:1;visibility:visible;pointer-events:auto;transition:opacity .14s}
.wf-hasacts.is-editing .wf-racts__cluster{
  opacity:0;visibility:hidden;pointer-events:none}
.wf-hasacts.is-editing .wf-racts .wf-editset{
  opacity:1;visibility:visible;pointer-events:auto;transition:opacity .14s}
.wf-racts .wf-act:hover,.wf-racts .wf-edit:hover{
  color:var(--label-hover);background:var(--row-hover)}
.wf-racts .wf-delete:hover{color:var(--dot-red,#C0584E);background:rgba(192,88,78,.10)}
/* no tree → no reserved chevron gap; pull the cluster to the edge */
.wf-racts--flush .wf-racts__cluster,
.wf-racts--flush .wf-editset{right:8px}
.wf-rexp{display:flex;align-items:center;justify-content:center;flex:none;
  width:26px;height:26px;border:0;background:transparent;color:var(--muted);
  cursor:pointer;transition:transform var(--dur) var(--ease),color .12s}
.wf-rexp svg{width:15px;height:15px;display:block}
.wf-hasacts:hover > .wf-racts > .wf-rexp{color:var(--label-hover)}
.wf-hasacts.is-open > .wf-racts > .wf-rexp{transform:rotate(90deg)}
/* When the action icons are hidden the title uses the full width
   (only the chevron lane is reserved). On hover/focus it eases
   narrower so the icons reveal — the chevron/icons never move
   (the grid is width-locked, so a long title just ellipsises). */
.wf-hasacts .wf-item__btn{padding-right:30px;
  transition:color .12s,padding-right .18s var(--ease)}
.wf-hasacts:hover .wf-item__btn,
.wf-hasacts:has(.wf-racts__cluster:focus-within) .wf-item__btn{
  padding-right:108px}

/* small breath between New workflow and Plan usage */
.wf-cta{margin-bottom:6px}



.wf-iconbtn:focus-visible,.wf-item__btn:focus-visible,
.wf-group__toggle:focus-visible{outline:0;box-shadow:inset 0 0 0 2px var(--focus)}
.wf-act:focus-visible,.wf-hint:focus-visible{outline:0;box-shadow:0 0 0 2px var(--focus)}

/* ---- COLLAPSED: single button (original compact icon) ---- */
.wf-nav.is-rail{padding:7px}
.wf-nav.is-rail .wf-nav__head{padding:0;justify-content:center}
.wf-nav.is-rail .wf-nav__title,
.wf-nav.is-rail .wf-search,
.wf-nav.is-rail .wf-cta,
.wf-nav.is-rail .wf-scroll,
.wf-nav.is-rail .wf-stats{display:none}

/* ---- STATS VIEW ---- */
.wf-stats{display:none;flex-direction:column;flex:1;min-height:0;
  opacity:0;transition:opacity .2s ease}
.wf-nav.is-stats .wf-search,
.wf-nav.is-stats .wf-cta,
.wf-nav.is-stats .wf-scroll{display:none}
.wf-nav.is-stats .wf-stats{display:flex;opacity:1}
.wf-stats__head{display:flex;align-items:center;gap:8px;padding:2px 2px 12px;
  border-bottom:1px solid var(--divider);margin-bottom:12px}
.wf-stats__back{display:flex;align-items:center;justify-content:center;width:28px;height:28px;
  border:0;background:transparent;color:var(--muted);border-radius:7px;cursor:pointer;flex:none;
  transition:background .12s,color .12s}
.wf-stats__back:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-stats__back svg{width:17px;height:17px}
.wf-stats__ttl{font-size:13px;font-weight:500;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}
.wf-stats__ttl small{display:block;font-size:11px;font-weight:400;color:var(--muted);
  letter-spacing:.04em;text-transform:uppercase;margin-top:1px}
.wf-stats__body{overflow-y:auto;flex:1;min-height:0;padding-right:2px;
  scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent}
/* clean summary — no boxed cards */
.wf-usage{padding:4px 2px 2px}
.wf-usage__spend{display:flex;align-items:baseline;gap:7px}
.wf-usage__spend b{font-size:26px;font-weight:500;color:var(--text)}
.wf-usage__spend span{font-size:11px;color:var(--muted);letter-spacing:.05em;
  text-transform:uppercase}
.wf-iobar{display:flex;height:6px;border-radius:3px;overflow:hidden;margin:12px 0 7px;
  background:rgba(64,78,71,.10)}
.wf-iobar i{display:block;height:100%;transition:width .6s var(--ease)}
.wf-iobar .in{background:var(--accent)}
.wf-iobar .out{background:var(--dot-orange)}
.wf-iolg{display:flex;justify-content:space-between;font-size:11.5px;color:var(--muted)}
.wf-iolg b{display:inline-block;width:7px;height:7px;border-radius:50%;
  margin-right:6px;vertical-align:1px}
.wf-iolg .in b{background:var(--accent)}
.wf-iolg .out b{background:var(--dot-orange)}
.wf-iolg strong{color:var(--text);font-weight:500;margin-left:4px}
.wf-sec-ttl{font-size:11px;letter-spacing:.06em;font-weight:500;color:var(--label);
  text-transform:uppercase;margin:18px 2px 6px}

/* expandable model rows */
.wf-modelwrap{border-radius:var(--radius)}
.wf-model{display:flex;align-items:center;gap:10px;width:100%;border:0;
  background:transparent;cursor:pointer;font:inherit;text-align:left;
  padding:9px 9px;border-radius:var(--radius);transition:background .12s}
.wf-model:hover{background:var(--row-hover)}
.wf-model__ic{width:18px;height:18px;flex:none;color:var(--icon);line-height:0}
.wf-model__ic svg{width:18px;height:18px}
.wf-model__nm{flex:1;min-width:0;font-size:13px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-model__tk{font-size:12px;color:var(--muted);flex:none}
.wf-model__chev{flex:none;color:var(--muted);line-height:0;
  transition:transform var(--dur) var(--ease),color .12s}
.wf-model__chev svg{width:13px;height:13px;display:block}
.wf-modelwrap.is-open .wf-model__chev{transform:rotate(90deg)}
.wf-modelwrap.is-open .wf-model__chev{color:var(--label-hover)}
.wf-model__panel{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows var(--dur-rev) var(--ease)}
.wf-modelwrap.is-open .wf-model__panel{grid-template-rows:1fr}
.wf-model__inner{overflow:hidden;overflow:clip;min-height:0}
.wf-kv{display:flex;justify-content:space-between;font-size:12.5px;
  padding:6px 9px 6px 38px}
.wf-kv:last-child{padding-bottom:9px}
.wf-kv span{color:var(--muted)}
.wf-kv strong{color:var(--text);font-weight:500}

/* ---- LIMITS (usage meters · color by how full) ---- */
.wf-plan{padding:8px 7px 9px}
.wf-meter{margin-bottom:15px;--m:#2F6E48}        /* ok · dark green */
.wf-meter.is-warn{--m:#9A6B2C}                   /* ~70% · muted amber */
.wf-meter.is-crit{--m:#9A4640}                   /* 90%+ · muted red */
.wf-meter:last-child{margin-bottom:3px}
.wf-meter__top{display:flex;justify-content:space-between;align-items:baseline;
  margin-bottom:7px}
.wf-meter__lblwrap{display:flex;align-items:center;min-width:0}
.wf-meter__lbl{font-size:12.5px;color:var(--text);letter-spacing:.01em}
.wf-meter__pct{font-size:11.5px;color:var(--muted);font-weight:500;
  font-variant-numeric:tabular-nums}
.wf-meter.is-warn .wf-meter__pct{color:#9A6B2C}
.wf-meter.is-crit .wf-meter__pct{color:#9A4640}
.wf-meter__track{height:6px;border-radius:3px;overflow:hidden;
  background:rgba(64,78,71,.10)}
.wf-meter__track i{display:block;height:100%;border-radius:3px;background:var(--m)}
.wf-meter__sub{display:flex;justify-content:space-between;
  font-size:11px;color:var(--muted);margin-top:6px;
  font-variant-numeric:tabular-nums}
.wf-meter__sub span{color:rgba(110,128,119,.78)}

/* ---- HINT TOOLTIP ---- */
.wf-tip{position:fixed;z-index:9999;display:none;pointer-events:none;
  font-family:inherit;font-size:12px;line-height:1.35;padding:7px 10px;
  border-radius:7px;max-width:230px;box-shadow:0 6px 22px rgba(0,0,0,.2);
  opacity:0;transition:opacity .12s}

/* ---- "NEED HELP?" — a subtle "?" chip OUTSIDE the panel, just
   past its right edge, level with the drag / pin / collapse
   buttons. On hover it widens to the words; on click the SAME
   container grows to hold the options (one morphing element).
   A transparent bridge means no dead gap to cross. ---- */
.wf-side{
  position:absolute;left:100%;top:15px;z-index:7;
  padding-left:6px;                 /* +2px right; transparent bridge */
  /* AirWanderer integration (Slice 4E-5 fix-pass 4): gap bumped
     from 8px to 14px so the second chip (Reduced motion) sits
     ~6px further below the first (Help) — far enough that its
     expanded pill no longer falls inside the canvas toolbar's
     vertical band + the chip-overlap detector's slop. Visually
     just slightly more breathing room in the strip. */
  display:flex;flex-direction:column;align-items:flex-start;gap:14px;
  transition:top .42s var(--ease);
  /* AirWanderer integration (Slice 4E-5 fix-pass): the side strip's
     transparent padding + gaps between chips previously captured
     clicks even though nothing visible was there. Make the strip
     itself click-through; the chips set pointer-events:auto on
     themselves when armed/hovered/open (see the rule below). The
     side's :hover-driven arming was lost as a side effect, but
     pointerenter on the nav top/head still arms via JS, and the
     chip-own :hover added below keeps the chip visible while the
     cursor is on it. */
  pointer-events:none}
/* aligned to the very top of the nav whenever it is shown (regardless
   of how the nav itself is positioned); it glides back to its normal
   placement once the nav is in workflow context again */
.wf-nav:not(.has-wfctx) .wf-side{top:0}
.wf-nav.has-wfctx .wf-side{top:15px}
/* in the usage view the Limits button lines up with the header
   collapse icon (.wf-nav__collapse), i.e. the normal 15px level */
.wf-nav.has-wfctx.is-stats .wf-side{top:15px}
/* while navigating Pages the chips line up with the header collapse
   icon too (same 15px level), not pinned to the very top */
.wf-nav.is-pages .wf-side{top:15px}
.wf-help,.wf-motion,.wf-limits{
  display:flex;align-items:flex-start;
  opacity:0;transform:translateX(-3px);pointer-events:none;
  /* Slice 4E-7D fix-pass: harmonized to .42s with no delay so the
     container fade/slide finishes at the same instant as the
     inner box-width / icon / text transitions. The previous .48s
     + .08s-delay combination was the slowest in the chain and
     was the visible last-to-finish "twitch" the user reported. */
  transition:opacity .42s var(--ease),transform .42s var(--ease)}
.wf-side.is-armed .wf-help,.wf-side:hover .wf-help,
.wf-side:focus-within .wf-help,.wf-help.is-open,.wf-help:hover,
.wf-side.is-armed .wf-motion,.wf-side:hover .wf-motion,
.wf-side:focus-within .wf-motion,.wf-motion:hover,
.wf-side.is-armed .wf-limits,.wf-side:hover .wf-limits,
.wf-side:focus-within .wf-limits,.wf-limits.is-open,.wf-limits:hover{
  /* AirWanderer integration (Slice 4E-5 fix-pass): chip-own :hover
     was added so a chip stays visible while the cursor is over it
     even after the disarmSoon 220 ms timer would otherwise remove
     is-armed. Without this, with .wf-side now pointer-events:none,
     the .wf-side:hover selector above no longer fires and a chip
     could fade out from under the cursor mid-flight. */
  opacity:1;transform:none;pointer-events:auto;transition-delay:0s}
/* widget open — the chip is swapped out for the floating panel */
.wf-limits.is-open .wf-limits__box{display:none}
/* AirWanderer integration (Slice 4E-5 fix-pass): when the panel is
   open AND has been dragged away from its default spot via the
   header drag, the .wf-limits container's layout box stays at the
   original side-strip position (the panel uses transform translate,
   which moves the panel visually but leaves its layout box where
   it was). Without this rule, the .wf-limits container at the
   original spot kept capturing clicks — visible as an invisible
   hitbox over canvas blocks behind the panel's old location. Making
   the open container click-through and re-asserting auto on the
   panel itself (which sits at the transformed location) routes
   clicks to the visible panel only; the original-position transparent
   area falls through to the canvas underneath. */
.wf-limits.is-open{pointer-events:none}
.wf-limits.is-open .wf-limitpanel{pointer-events:auto}
/* the Limits chip is available while navigating Pages too (same
   hover/arm reveal as Help / Reduced motion) so the widget can be
   opened there; opening docks it below the nav */
/* the single container that morphs between all three states.
   Its WIDTH is driven explicitly per state so the collapsed
   chip hugs the "?" and the open menu is comfortably wide. */
.wf-help__box{
  display:flex;flex-direction:column;overflow:hidden;
  width:32px;                              /* collapsed: just "?" */
  background:var(--surface);
  border:1px solid rgba(255,255,255,.55);
  border-radius:9px;
  box-shadow:0 2px 9px rgba(55,72,64,.07);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  /* Slice 4E-7D fix-pass: harmonized every inner transition to
     the box-width .42s timing with no delays — mismatched
     durations (icon .34s, opacity .28s, text .42s with .08s
     delay, button .4s, border-radius .26s) caused the layout to
     settle in stages and produced the "twitch" the user saw at
     the end of the collapse. With every transition completing at
     the same instant the chip glides cleanly. */
  transition:width .42s var(--ease),border-radius .42s var(--ease)}
.wf-help:hover .wf-help__box,
.wf-help:focus-within .wf-help__box{width:132px}    /* pill */
.wf-help.is-open .wf-help__box{width:186px}         /* menu  */
.wf-help__btn{
  display:flex;align-items:center;justify-content:center;width:100%;
  border:0;background:transparent;cursor:pointer;color:var(--muted);
  font:inherit;font-size:12px;letter-spacing:.01em;text-transform:none;
  padding:7px;border-radius:9px;white-space:nowrap;
  /* Slice 4E-7D fix-pass: harmonized to .42s — see .wf-help__box. */
  transition:color .42s var(--ease),gap .42s var(--ease),
             justify-content .42s var(--ease),padding .42s var(--ease)}
.wf-help__ic{display:flex;align-items:center;justify-content:center;
  width:17px;max-width:17px;opacity:1;flex:none;overflow:hidden;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
.wf-help__ic svg{width:16px;height:16px;display:block}
.wf-help__txt{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
/* on hover / open the "?" is replaced by the words entirely */
.wf-help:hover .wf-help__ic,.wf-help:focus-within .wf-help__ic,
.wf-help.is-open .wf-help__ic{max-width:0;opacity:0}
.wf-help:hover .wf-help__btn,.wf-help:focus-within .wf-help__btn,
.wf-help.is-open .wf-help__btn{
  color:var(--label-hover);justify-content:flex-start;
  padding:7px 12px 7px 11px}
.wf-help:hover .wf-help__txt,.wf-help:focus-within .wf-help__txt,
.wf-help.is-open .wf-help__txt{max-width:150px;opacity:1}
/* options live INSIDE the same box and unfold beneath the
   trigger — the container grows as one piece */
.wf-help__menu{
  display:flex;flex-direction:column;gap:2px;
  max-height:0;opacity:0;overflow:hidden;padding:0 6px;
  transition:max-height .26s var(--ease),opacity .18s var(--ease),
             padding .26s var(--ease)}
.wf-help.is-open .wf-help__menu{
  max-height:120px;opacity:1;padding:2px 6px 6px;
  border-top:1px solid var(--divider)}
.wf-help__opt{
  display:flex;align-items:center;gap:9px;width:100%;
  border:0;background:transparent;cursor:pointer;
  font:inherit;font-size:13px;letter-spacing:0;text-transform:none;
  color:var(--text);white-space:nowrap;
  padding:8px 9px;border-radius:7px;text-align:left;
  transition:background .12s,color .12s}
.wf-help__opt:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-help__opt svg{width:15px;height:15px;display:block;flex:none;color:var(--muted)}
.wf-help__opt:hover svg{color:var(--label-hover)}
.wf-nav.is-rail .wf-side{display:none}
/* in the usage view Help/Reduced-motion are not shown, so the Limits
   button takes their place at the very top of .wf-side */
.wf-nav.is-stats .wf-help,
.wf-nav.is-stats .wf-motion{display:none}

/* ---- reduced-motion toggle: same chip mechanics as Help ---- */
.wf-motion__box{
  display:flex;overflow:hidden;
  width:32px;                              /* collapsed: just the icon */
  background:var(--surface);
  border:1px solid rgba(255,255,255,.55);
  border-radius:9px;
  box-shadow:0 2px 9px rgba(55,72,64,.07);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  /* Slice 4E-7D fix-pass: harmonized every transition to .42s
     so the collapse settles at a single instant, eliminating the
     end-of-collapse "twitch". */
  transition:width .42s var(--ease),border-color .42s var(--ease),
             background .42s var(--ease)}
.wf-motion:hover .wf-motion__box,
.wf-motion:focus-within .wf-motion__box{width:132px}   /* pill (matches Help) */
.wf-motion__btn{
  display:flex;align-items:center;justify-content:center;width:100%;
  border:0;background:transparent;cursor:pointer;color:var(--muted);
  font:inherit;font-size:12px;letter-spacing:.01em;text-transform:none;
  padding:7px;border-radius:9px;white-space:nowrap;
  transition:color .42s var(--ease),justify-content .42s var(--ease),
             padding .42s var(--ease)}
.wf-motion__ic{display:flex;align-items:center;justify-content:center;
  width:17px;max-width:17px;opacity:1;flex:none;overflow:hidden;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
.wf-motion__ic svg{width:16px;height:16px;display:block}
.wf-motion__txt{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
.wf-motion:hover .wf-motion__ic,
.wf-motion:focus-within .wf-motion__ic{max-width:0;opacity:0}
.wf-motion:hover .wf-motion__btn,
.wf-motion:focus-within .wf-motion__btn{
  color:var(--label-hover);justify-content:flex-start;
  padding:7px 12px 7px 11px}
.wf-motion:hover .wf-motion__txt,
.wf-motion:focus-within .wf-motion__txt{max-width:150px;opacity:1}
/* enabled state: accent, mirroring the pinned-button language */
.wf-motion.is-on .wf-motion__box{
  border-color:rgba(92,154,126,.55);
  background:linear-gradient(var(--header-hover),var(--header-hover)),var(--surface)}
.wf-motion.is-on .wf-motion__btn{color:var(--accent)}
.wf-motion.is-on .wf-motion__ic{color:var(--accent)}

/* ---- Limits: same chip language as Help / Reduced motion ----
   (a flex child of .wf-side — no absolute positioning of its own;
   reveal is driven by the shared .wf-side rules above) */
.wf-limits__box{
  display:flex;overflow:hidden;width:32px;
  background:var(--surface);border:1px solid rgba(255,255,255,.55);
  border-radius:9px;box-shadow:0 2px 9px rgba(55,72,64,.07);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  /* Slice 4E-7D fix-pass: harmonized to .42s across the board. */
  transition:width .42s var(--ease),border-color .42s var(--ease),
             background .42s var(--ease)}
.wf-limits:hover .wf-limits__box,
.wf-limits:focus-within .wf-limits__box{width:108px}
.wf-limits__btn{
  display:flex;align-items:center;justify-content:center;width:100%;
  border:0;background:transparent;cursor:pointer;color:var(--muted);
  font:inherit;font-size:12px;letter-spacing:.01em;
  padding:7px;border-radius:9px;white-space:nowrap;
  transition:color .42s var(--ease),justify-content .42s var(--ease),
             padding .42s var(--ease)}
.wf-limits__ic{display:flex;align-items:center;justify-content:center;
  width:17px;max-width:17px;opacity:1;flex:none;overflow:hidden;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
.wf-limits__ic svg{width:16px;height:16px;display:block}
.wf-limits__txt{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;
  transition:max-width .42s var(--ease),opacity .42s var(--ease)}
.wf-limits:hover .wf-limits__ic,
.wf-limits:focus-within .wf-limits__ic{max-width:0;opacity:0}
.wf-limits:hover .wf-limits__btn,
.wf-limits:focus-within .wf-limits__btn{
  color:var(--label-hover);justify-content:flex-start;
  padding:7px 12px 7px 11px}
.wf-limits:hover .wf-limits__txt,
.wf-limits:focus-within .wf-limits__txt{max-width:90px;opacity:1}

/* the widget opens in place of its chip, inside the .wf-limits slot
   of .wf-side — so it appears exactly where .wf-limits__btn was, in
   both the normal and the usage view. Layout shifts from toggling
   usage are neutralised in JS (FLIP) so a dragged-open widget stays
   put. Draggable via transform; nav drag is compensated in JS. */
.wf-limitpanel{
  /* AirWanderer integration (Slice 4E-5 fix-pass 5): styling is
     IDENTICAL to .wf-nav — same --surface, --border, --shadow,
     --blur, --radius-lg tokens, no scoped overrides. Width is
     set dynamically in JS to follow the live nav width (popout)
     or the nav rect (docked); the fallback below only applies on
     the first paint before openLimits() runs. */
  position:relative;z-index:8;width:240px;display:none;
  background-color:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  transform-origin:0 0}
.wf-limitpanel.is-open{display:block;animation:wf-lim-in .24s var(--ease) both}
/* opacity-only so it never overrides the drag/compensation transform */
@keyframes wf-lim-in{ from{opacity:0} to{opacity:1} }
.wf-limitpanel.is-dragging{will-change:transform}
/* Pages: a separate, fixed card docked beneath the nav. left/top/
   width are set inline from the live nav rect; it reads as a sibling
   container of the nav (slightly lifted shadow). */
.wf-limitpanel.is-docked{
  position:fixed;z-index:60;animation:none;
  /* AirWanderer integration (Slice 4E-5 fix-pass 3): use the same
     --shadow token as .wf-nav so the docked card reads as a
     sibling of the nav with matching elevation. */
  box-shadow:var(--shadow);
  /* docked — hoisted out of .wf-nav to <body> (so position:fixed is
     viewport-anchored). Re-declare the token palette so the card keeps
     its theme outside the nav's variable scope.
     AirWanderer integration (Slice 4E-5 fix-pass 5): --surface
     matches the nav's exactly (.56) — styling is identical. */
  --surface:rgba(255,255,255,.56);
  --border:rgba(255,255,255,.70);
  --divider:rgba(70,92,80,.16);
  --label:#41584C;
  --label-hover:#27543C;
  --text:#1F2D26;
  --muted:#6E8077;
  --row-hover:rgba(60,74,67,.06);
  --accent:#5C9A7E;
  --dot-green:#4FA37C;
  --dot-orange:#E8C08A;
  --dot-black:#2B332E;
  --dot-gray:#A7B0AA;
  --scroll-thumb:rgba(90,112,100,.30);
  --blur:blur(20px) saturate(180%) brightness(1.03);
  --radius:9px;
  --radius-lg:16px;
  --ease:cubic-bezier(.32,.72,0,1);
  --dur:.24s;
  --dur-rev:.42s}
.wf-limitpanel.is-docked .wf-limitpanel__h{cursor:default}
/* AirWanderer integration (Slice 4E-5 fix-pass 2): in docked Pages
   view the panel reads as a permanent docked card — no drag, no
   reset, no close. The chip in the side strip toggles it. Hiding
   the whole header here keeps the docked panel maximally compact;
   the workflow-view popout (no .is-docked) still shows the header. */
.wf-limitpanel.is-docked .wf-limitpanel__h{display:none}
/* Pages: the close affordance stays out of the way until you’re
   actually on the card (keyboard focus reveals it too) */
.wf-limitpanel.is-docked .wf-limitpanel__x{
  opacity:0;pointer-events:none;
  transition:opacity .15s var(--ease),background .12s,color .12s}
.wf-limitpanel.is-docked:hover .wf-limitpanel__x,
.wf-limitpanel.is-docked:focus-within .wf-limitpanel__x{
  opacity:1;pointer-events:auto}
/* FLIP: invert instantly, then release with a smooth glide */
.wf-limitpanel.is-flip{transition:none !important}
.wf-limitpanel.is-docksliding{transition:transform .42s var(--ease)}
/* during the nav reposition-reset, the widget counter-moves with the
   exact same timing as the nav so it appears to stay perfectly still */
.wf-limitpanel.is-navsync{transition:transform var(--dur) var(--ease)}
.wf-limitpanel__h{
  /* AirWanderer integration (Slice 4E-5 fix-pass 3): "Limits" title
     on the left (flex:1 pushes the control cluster to the right),
     drag indicator + reset + close clustered on the right in that
     order. Drag and reset are hover-revealed; close is always
     visible. Header stays draggable (cursor:grab) so the whole
     row works as the drag handle. */
  display:flex;align-items:center;gap:2px;
  padding:6px 8px;cursor:grab;
  border-bottom:1px solid var(--divider);touch-action:none;min-height:32px}
.wf-limitpanel.is-dragging .wf-limitpanel__h{cursor:grabbing}
.wf-limitpanel__t{
  flex:1;min-width:0;color:var(--label);
  font-size:11px;letter-spacing:.07em;font-weight:600;text-transform:uppercase;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  pointer-events:none;user-select:none}
.wf-limitpanel__r,
.wf-limitpanel__x{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:24px;height:24px;border:0;background:transparent;
  color:var(--muted);border-radius:7px;cursor:pointer;
  transition:background .12s,color .12s}
.wf-limitpanel__r:hover,
.wf-limitpanel__x:hover{background:var(--row-hover);color:var(--label-hover)}
.wf-limitpanel__r svg,
.wf-limitpanel__x svg{width:15px;height:15px;display:block}
/* AirWanderer integration (Slice 4E-5 fix-pass 3): drag-handle
   indicator at the LEFT of the right-cluster (i.e. just before the
   reset/close pair). Mirrors the left nav's .wf-nav__drag behaviour
   — hidden by default, glides to full width on header hover so the
   user can see the panel is draggable without cluttering at rest. */
.wf-limitpanel__drag{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:0;opacity:0;color:var(--muted);overflow:hidden;
  pointer-events:none;
  transition:width .26s var(--ease),opacity .26s var(--ease)}
.wf-limitpanel__drag svg{width:15px;height:15px;display:block}
.wf-limitpanel:hover .wf-limitpanel__drag{
  width:18px;opacity:1}
/* AirWanderer integration (Slice 4E-5 fix-pass 3): reset button is
   between drag and close in the right cluster — only visible once
   the panel has been moved AND the header is hovered. Same easing
   /timing as the drag indicator so the two icons fade in together.
   The title's flex:1 already pushes the whole cluster right, so no
   margin-left:auto is needed on __r or __x. */
.wf-limitpanel__r{
  width:0;opacity:0;pointer-events:none;overflow:hidden;
  transition:width .26s var(--ease),opacity .26s var(--ease),
             background .12s,color .12s}
.wf-limitpanel.is-moved:hover .wf-limitpanel__r{
  width:24px;opacity:1;pointer-events:auto}
.wf-limitpanel__b{padding:9px 13px 9px}
/* compact meter rhythm — only inside the widget — so the panel
   ends roughly where a collapsed nav (head + sub only) does */
.wf-limitpanel__b .wf-meter{margin-bottom:12px}
.wf-limitpanel__b .wf-meter:last-child{margin-bottom:0}
.wf-limitpanel__b .wf-meter__top{margin-bottom:4px}
.wf-limitpanel__b .wf-meter__sub{margin-top:3px}

/* ---- global reduced-motion: make every transition / animation
   inside the panel effectively instant ---- */
.wf-nav.is-reduced,
.wf-nav.is-reduced *,
.wf-nav.is-reduced *::before,
.wf-nav.is-reduced *::after{
  transition-duration:.001ms !important;
  animation-duration:.001ms !important;
  animation-delay:0s !important;
  animation-iteration-count:1 !important;
  scroll-behavior:auto !important}

/* ==========================================================================
   ROUND 23 (owner report 3, track H): "when I click the logo when viewing the
   pages, the nav ... is not aligned by the size with the logo".
   On the canvas route the rail is a 40 x 42 card (saas-shell.css / topbar.css:
   width 40, padding 0, radius 12) sitting 16 px under the collapsed logo
   (--aw-bar-bottom 74 = logo bottom 58 + 16). On a page route the component's
   own rail rule won (52 px wide, 7 px padding) and the nav's margin-top kept
   the EXPANDED bar's 78 px, so the rail read 52 x 56 at y 78 next to a 40 x 40
   logo at y 18 (measured: spec 36 arm C on HEAD). Same card, same column, same
   gap here. The logo is 40 tall at top 18 (bar-gap 14 + (48 - 40) / 2), so the
   rail's top is 18 + 40 + 16 = 74 on both routes. */
body.route-page .wf-nav.is-pages.is-rail{
  width:40px!important;
  padding:0!important;
  border-radius:12px!important;
  margin-top:calc(var(--bar-gap, 14px) + 4px + 40px + 16px)!important;
}
body.route-page .wf-nav.is-pages.is-rail .wf-nav__head{padding:0;justify-content:center}
body.route-page .wf-nav.is-pages.is-rail .wf-iconbtn.wf-nav__collapse{
  width:38px!important;height:38px!important;border-radius:11px!important;padding:0!important}

/* ROUND 23 (owner report 8, track H): the Limits panel's plain rows - a count
   (tokens) and a money amount (cost) that have no cap and so no meter bar -
   and the plan line above the meters. Same type as the meters' labels. */
.wf-limitpanel__plan{display:flex;align-items:center;gap:4px;margin:0 0 10px;
  font-size:11.5px;color:var(--muted);letter-spacing:.02em;text-transform:uppercase}
.wf-limitpanel__plan .wf-hint{margin-left:2px}
.wf-lrow{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:11px}
.wf-lrow:last-child{margin-bottom:3px}
.wf-lrow__lblwrap{display:flex;align-items:center;min-width:0}
.wf-lrow__lbl{font-size:12.5px;color:var(--text);letter-spacing:.01em}
.wf-lrow__val{font-size:12.5px;color:var(--text);font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap}
.wf-lrow:hover .wf-hint{opacity:1}
