/* ============================================================================
   wci-modules.css: the Module shell (INTEL-426 Sticky modules, INTEL-392 Width toggle).
   The rules WciModuleRow and WciModule share: the row, the chat as the buckle, drawers tucked behind it,
   nested drawers one layer deeper, the width tiers, the drag seams and the progress restore tab.
   Global rather than scoped because the belt is a relationship between components: the row's rules reach
   modules rendered by other components, and a scoped sheet cannot.

   Source (ip-b2b, served by the prototype host 2026-09-29; see REGISTRY.md rule 7):
     pages/wise.css 3482-3542  #modules-row, the tuck tokens and child sizing
     pages/wise.css 3587-3641  the z-index ladder and the generic .sticky-mod.is-sticky drawer
     pages/wise.css 3653-3694  drawers whose card is an inner element (the progress tracker)
     pages/wise.css 3695-3705  a drawer with an open menu keeps its layer
     pages/wise.css 3718-3730  stickySlideRight and its reduced-motion guard
     pages/wise.css 3732-3759  nested drawers (z-index 0, the 50px tuck)
     pages/wise.css 3843-3882  the progress restore tab
     pages/wise.css 3891-3900  the row's thin scrollbar
     pages/wise.css 3910-3939  the <= 560px stack
     js/chat-history.js 395-441  the docked History (left) and Turns (right) drawers and their head
     js/pane-width.js 631-657    the fill / custom / carousel rules the script injects
     js/pane-resize.js 823-853   the drag seam grip the script injects
   Class names are the design's, with one change: the design's row is an id (#modules-row) because a
   prototype page has one; a Blazor page can hold two (the chat page and an AI drawer), so the id is the
   class .modules-row here, which pane-width.js already accepts as a synonym. The design's list of
   per-page chat and drawer ids (#wa-chat, #agent-main, #nfp-panel, ...) collapses to the classes
   WciModule renders for its Layer.
   ============================================================================ */

/* ---- Row and tuck tokens (wise.css 3482-3514) ---- */
.modules-row {
  flex: 1 1 0%;
  min-height: 0;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  overflow-x: auto;
  overflow-y: hidden;
  background: var(--bg);
  --sticky-tuck: 14px;
  --sticky-pad: 14px;
  --sticky-nested-tuck: 50px;
  --sticky-nested-pad: 30px;
  --sticky-nested-inner: 20px;
  --sticky-nested-face-pad: 50px;
  padding: 0 16px;
  gap: 8px;
  scrollbar-gutter: stable;
}

/* ---- Children fill the row (wise.css 3538-3542) ---- */
.modules-row > * {
  height: 100%;
  max-height: 100%;
  align-self: stretch;
}

/* ---- The chat is the buckle (wise.css 3587-3602) ---- */
.modules-row { position: relative; }
.modules-row > .sticky-chat {
  position: relative;
  z-index: 3 !important;
}

/* ---- Output sits under the chat and over its peers (wise.css 3613-3619) ---- */
.modules-row > .wci-module--output.sticky-mod.is-sticky { z-index: 2; }

/* ---- The generic drawer (wise.css 3620-3641) ---- */
.modules-row .sticky-mod.is-sticky {
  position: relative;
  z-index: 1;
  background: var(--surface);
  box-shadow: none;
  align-self: center;
  height: calc(100% - 30px);
  margin-left: calc(-1 * var(--sticky-tuck) - var(--modules-gap, 8px));
  padding-left: var(--sticky-pad);
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  border-top-right-radius: var(--r-md, 16px);
  border-bottom-right-radius: var(--r-md, 16px);
  border-left: 0;
  animation: stickySlideRight .42s cubic-bezier(.34, 1.45, .64, 1) both;
}

/* ---- Drawers whose card frame is an inner element (the progress tracker's .vfp-inner)
   (wise.css 3653-3694, the design's list trimmed to the classes the app renders) ---- */
.modules-row .vf-progress-pane > .vfp-inner {
  border-top-left-radius: 0 !important;
  border-bottom-left-radius: 0 !important;
  border-top-right-radius: var(--r-md, 16px) !important;
  border-bottom-right-radius: var(--r-md, 16px) !important;
  border-left: 0 !important;
  box-shadow: none !important;
}
.modules-row .vf-progress-pane.sticky-mod.is-sticky > .vfp-inner {
  padding-left: var(--sticky-nested-inner);
  box-sizing: border-box;
}
.modules-row .sticky-mod.is-sticky:has(> [class*="-inner"]) {
  background: transparent;
}
.modules-row .sticky-mod.is-sticky:has(> [class*="-inner"])::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--sticky-pad);
  background: var(--surface);
  pointer-events: none;
  z-index: 0;
}

/* ---- A drawer's open menu never lifts it over the chat (wise.css 3695-3705) ---- */
.modules-row .sticky-mod.is-sticky:has(.panel-more-btn.is-open),
.modules-row .sticky-mod.is-sticky:has(.topbar-popover:not(.hidden)) {
  z-index: 1;
}
.modules-row .wci-module--output.sticky-mod.is-sticky:has(.panel-more-btn.is-open),
.modules-row .wci-module--output.sticky-mod.is-sticky:has(.topbar-popover:not(.hidden)) {
  z-index: 2;
}

/* ---- Slide-in (wise.css 3718-3730) ---- */
@keyframes stickySlideRight {
  from { transform: translateX(-26px); opacity: .35; }
  to   { transform: none; opacity: 1; }
}
.modules-row .sticky-mod.is-sticky.is-entered { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .modules-row .sticky-mod.is-sticky { animation: none !important; }
}

/* ---- Nested drawers: z-index 0, tucked 50px under their parent (wise.css 3732-3759) ----
   The design's comment (3740-3741) settles the card's "~30px shorter still": the same 15px inset as the
   module it tucks behind, never a second, shorter height. */
.modules-row .wci-module--nested.sticky-mod.is-sticky,
.modules-row .vf-progress-pane.sticky-mod.is-sticky {
  z-index: 0;
  height: calc(100% - 30px) !important;
  max-height: calc(100% - 30px) !important;
  align-self: center !important;
  margin-left: calc(-1 * var(--sticky-nested-tuck) - var(--modules-gap, 8px)) !important;
  padding-left: var(--sticky-nested-pad) !important;
}
/* Nested drawers stay on layer 0 while their menu is open (wise.css 3830-3841). */
.modules-row .wci-module--nested.sticky-mod.is-sticky:has(.panel-more-btn.is-open),
.modules-row .vf-progress-pane.sticky-mod.is-sticky:has(.panel-more-btn.is-open),
.modules-row .vf-progress-pane.sticky-mod.is-sticky:has(.topbar-popover:not(.hidden)) {
  z-index: 0;
}

/* ---- Progress restore tab (wise.css 3843-3882) ---- */
.modules-row .wise-progress-restore {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: auto;
  padding: 10px 6px;
  border: 1px solid var(--border);
  border-right: 0;
  border-top-left-radius: 12px;
  border-bottom-left-radius: 12px;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  background: var(--surface);
  color: var(--text-muted);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  font: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  writing-mode: vertical-rl;
  transition: color .15s ease, background .15s ease;
}
.modules-row .wise-progress-restore:hover {
  color: var(--text);
  background: var(--surface-2);
  border-color: var(--primary);
}
.modules-row .wise-progress-restore .material-symbols-outlined {
  font-size: 18px;
  writing-mode: horizontal-tb;
}
.modules-row .wise-progress-restore .wpr-label { letter-spacing: 0.04em; }

/* ---- Scrollbar (wise.css 3891-3900) ---- */
.modules-row::-webkit-scrollbar { height: 8px; }
.modules-row::-webkit-scrollbar-track { background: transparent; }
.modules-row::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-subtle) 35%, transparent);
  border-radius: 999px;
}
.modules-row {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--text-subtle) 35%, transparent) transparent;
}

/* ---- Docked History (left) and Turns (right) (js/chat-history.js 395-441) ----
   The design's .wch-sidebar.wch-docked drawers under .modules-sticky, which is permanent on the WISEcodeAI
   page (wiseai.html 4436-4439): here the recessed drawer is .wci-module--recessed, the right one is the
   plain .sticky-mod rule above, and the left one mirrors it. */
.modules-row .wci-module--recessed.sticky-mod.is-sticky {
  z-index: 1;
  background: var(--surface-2, var(--surface));
  box-shadow: none;
}
.modules-row .wci-module--left.sticky-mod.is-sticky {
  margin-left: 0;
  padding-left: 0;
  margin-right: calc(-1 * var(--sticky-tuck, 14px) - var(--modules-gap, 8px));
  padding-right: var(--sticky-pad, 14px);
  border-top-left-radius: var(--r-md, 16px);
  border-bottom-left-radius: var(--r-md, 16px);
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-left: 1px solid var(--border);
  border-right: 0;
  animation: none;
}
.modules-row .wci-module .wch-head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  flex-shrink: 0;
  padding: var(--module-head-pad-t, 26px) var(--module-head-ctrl-inset, 12px) var(--module-head-pad-b, 14px) var(--module-head-pad-l, 20px);
  border-bottom: 1px solid var(--border, rgba(0, 0, 0, 0.08));
}
.modules-row .wci-module .wch-head-title {
  flex: 1;
  min-width: 0;
  font-family: "WISE Digits", var(--module-title-family, "Noto Serif", serif);
  font-weight: var(--module-title-weight, 800);
  font-size: var(--module-title-size, 1.2rem);
  letter-spacing: -.01em;
  line-height: var(--module-title-lh, 1.16);
  color: var(--text);
  margin: 0;
}
.modules-row .wci-module .wch-controls {
  display: inline-flex;
  align-items: center;
  gap: var(--module-head-ctrl-gap, 2px);
  margin-top: 0;
}
@keyframes wchDockRevealL { from { opacity: 0; transform: translateX(46px) scale(.97) } to { opacity: 1; transform: none } }
.modules-row .wci-module--left.sticky-mod.is-sticky.wch-dock-reveal { animation: wchDockRevealL .44s cubic-bezier(.34, 1.4, .64, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .modules-row .wci-module--left.sticky-mod.is-sticky.wch-dock-reveal { animation: none; }
}

/* ---- Width tiers: fill, custom and the carousel rail (js/pane-width.js injectStyles() 631-657) ----
   The design writes each host's preset widths into that host's own rules (the chat's 380 / 580px, Turns'
   280 / 420px, ...). WciModule carries them as --wci-mod-single / --wci-mod-double on the module, so one
   set of rules serves every host; see the app-owned block below. */
.modules-row.modules-carousel {
  overflow-x: auto !important;
  overflow-y: hidden;
  scrollbar-gutter: stable;
}
.modules-row.modules-carousel::-webkit-scrollbar { height: 10px; }
.modules-row.modules-carousel::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-subtle) 55%, transparent);
  border-radius: 999px;
}
.modules-row.modules-carousel > * { flex-shrink: 0 !important; }

/* ---- Drag seams (js/pane-resize.js injectStyles() 823-853) ---- */
.pr-handle {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  cursor: col-resize;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.pr-grip {
  display: block;
  width: 6px;
  height: 40px;
  border-radius: 6px;
  background: rgba(16, 24, 32, .78);
  border: 1px solid rgba(255, 255, 255, .6);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .45);
  position: relative;
  opacity: 0;
  transform: scaleY(.5);
  transition: opacity .12s ease, transform .12s ease, width .12s, background .12s, border-color .12s;
}
.pr-grip::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 -5px 0 #fff, 0 5px 0 #fff;
}
.pr-handle:hover .pr-grip,
.pr-handle:focus-visible .pr-grip,
.pr-handle.pr-active .pr-grip { opacity: 1; transform: scaleY(1); }
.pr-handle.pr-active .pr-grip {
  width: 8px;
  background: var(--primary, #25507C);
  border-color: var(--primary, #25507C);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary, #25507C) 32%, transparent), 0 3px 14px rgba(0, 0, 0, .5);
}
html.pr-dragging,
html.pr-dragging * {
  cursor: col-resize !important;
  -webkit-user-select: none !important;
  user-select: none !important;
}

/* ---- The <= 560px stack (wise.css 3910-3939) ----
   Below this width the row drops into a single column. The design names its page modules by id; every
   WciModule takes the stacked shape here, and the tuck, the inset and the seams stand down. */
@media (max-width: 560px) {
  .modules-row {
    flex-direction: column;
    flex-wrap: nowrap;
    overflow-x: hidden;
    overflow-y: auto;
  }
  .modules-row > .wci-module,
  .modules-row > .vf-progress-pane {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    height: auto !important;
    max-height: none !important;
    flex: 0 0 auto !important;
    align-self: stretch !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 1px solid var(--border) !important;
    border-radius: var(--r-md, 16px) !important;
  }
  /* A custom width leaves the carousel class on the row; its sideways overflow must not survive the stack. */
  .modules-row.modules-carousel { overflow-x: hidden !important; overflow-y: auto; }
  .modules-row > .sticky-chat { min-height: 70dvh; }
  .modules-row > .sticky-mod { min-height: 50dvh; }
  .modules-row .wci-seams { display: none !important; }
}

/* ============================================================================
   APP-OWNED ADDITIONS (not in wise.css)
   ============================================================================ */

/* The module card. The design's modules are each their own card (.sc-card for the chat, the page's pane
   classes for the rest); WciModule is one element for all of them, so the frame lives here. The sticky
   rules above then square, tuck and recess it. */
.wci-module {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  box-sizing: border-box;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md, 16px);
  overflow: hidden;
}
.modules-row > .sticky-chat { box-shadow: var(--chat-elev, var(--shadow-card)); }
.wci-module-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* A dialog opened from inside a module. A module's z-index (3 for the chat, 0-2 for drawers) makes it a
   stacking context, so a WciModal or a fullscreen card overlay rendered inside it (the chat's Export
   dialog, TurnCard's overlay) would paint under the page's own layers, the nav at 55-70 among them. The
   design never meets this because its popovers portal to <body>; here the module lifts to the dialog
   layer (wci-dialog.css, 10100) only while one is open, and drops back to its place on the belt after. */
.modules-row > .wci-module:has(.wise-modal-scrim),
.modules-row > .wci-module:has(.fixed.inset-0) {
  z-index: 10100 !important;
}

/* Preset widths. Single and double are the host's own lengths (WciModule SingleWidth / DoubleWidth), fill
   absorbs the rest of the row, custom holds the dragged pixel width. The design's fill is
   flex-basis: auto, which sizes a module from its max-content first; a chat's 860px reading column then
   out-shouts its neighbours before the grow is shared, so fill here starts from 0. */
.modules-row > .wci-module {
  flex: 0 0 var(--wci-mod-single, 380px);
  width: var(--wci-mod-single, 380px);
}
.modules-row > .wci-module.panel-wide {
  flex-basis: var(--wci-mod-double, 580px);
  width: var(--wci-mod-double, 580px);
}
.modules-row > .wci-module.panel-fill,
.modules-row > .wci-module.wci-module--solo {
  flex: 1000 1 0%;
  width: auto;
  max-width: none;
}
.modules-row > .wci-module.panel-custom {
  flex: 0 0 var(--wci-mod-w, var(--wci-mod-single, 380px));
  width: var(--wci-mod-w, var(--wci-mod-single, 380px));
  max-width: none;
}
/* Every drawer keeps a 300px floor (pane-resize.js MIN_W) so a filling neighbour never crushes it; a
   module narrower by design (the History rail) declares its own. */
.modules-row > .wci-module.sticky-mod { min-width: min(var(--wci-mod-min, 300px), var(--wci-mod-single, 380px)); }
.modules-row > .wci-module.sticky-chat { min-width: min(300px, var(--wci-mod-single, 380px)); }

/* The width tween: a tap eases to the new width, a drag does not (the script sets .pr-dragging). */
.modules-row > .wci-module { transition: flex-basis .22s ease, width .22s ease; }
html.pr-dragging .modules-row > .wci-module { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .modules-row > .wci-module { transition: none; }
}

/* The seam layer: the script draws the handles inside the row's own .wci-seams layer (the design uses a
   body-level fixed overlay, which lands in the wrong place inside the AI drawer's transform), above every
   layer, the restore tab included. The layer itself takes no pointer and no slot in the flex row. */
.wci-seams {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  height: auto !important;
  max-height: none !important;
  align-self: auto !important;
  width: auto;
  flex: none;
}
.wci-seams > .pr-handle { pointer-events: auto; }

/* A dock (the AI drawer) is not in a row: its one handle rides its left edge. */
.wci-dock > .wci-seams > .pr-handle { top: 12%; bottom: 12%; left: -9px; width: 18px; }
/* A closed dock stays mounted, slid off the right edge; its handle pokes 9px out of its left edge, which
   would leave a live strip on the viewport's edge. Hidden, it also leaves the tab order. */
.wci-dock:not(.is-open) > .wci-seams { display: none; }

/* The AI drawer's four widths (the design's .wiseai-dock tiers, wise.css 7867-7895: 380px, min(580px, 90vw),
   fill). The drawer floats over the page instead of taking a slot in a row, so fill reaches from the
   primary nav's edge (the same offset sidebar.css gives .main-content) to the viewport's right edge. */
body { --wci-dock-inset: 0px; }
body:has(#sidebar.sidebar-expanded) { --wci-dock-inset: calc(var(--sidebar-gap, 12px) + var(--sidebar-w, 272px) + 16px); }
body:has(#sidebar.sidebar-collapsed) { --wci-dock-inset: calc(var(--sidebar-gap, 12px) + var(--sidebar-w-collapsed, 76px) + 16px); }
@media (max-width: 768px) {
  body:has(#sidebar) { --wci-dock-inset: 0px; }
}
.wci-dock { width: 380px; max-width: 100vw; transition: width .22s ease, transform .3s ease-in-out; }
.wci-dock.panel-wide { width: min(580px, 90vw); }
.wci-dock.panel-fill { width: calc(100vw - var(--wci-dock-inset)); }
.wci-dock.panel-custom { width: min(var(--wci-mod-w, 380px), 100vw); }
html.pr-dragging .wci-dock { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .wci-dock { transition: none; }
}
@media (max-width: 560px) {
  .wci-dock, .wci-dock.panel-wide, .wci-dock.panel-fill, .wci-dock.panel-custom { width: 100vw; }
  .wci-dock > .wci-seams { display: none; }
}
