/* ═══════════════════════════════════════════════════════════════════════════════════
   REDESIGN — POS page and its docked side panels
   Sources: 00-SPEC §10 / §12 / §16, proto/index.html #s-pos, files/02-pos-page.html,
   files/04-pos-side-panels.html. Loads after app.css and overrides it by id specificity.
   No imports and no relative resource targets — the shell contract rejects both, and
   its checks scan this file's text, so neither word may appear even in a comment.
   ═══════════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · POS page, deal row ──────────────────────────────────────────────────────────
   §10: the cash split control sits on the same horizontal row, pushed to the right.
   Shipped DOM order is customerBar, lotBar, fundBar, channelBar, Clear deal, and
   public/index.html belongs to the integrator, so the row is reordered here instead.
   ✕ Clear deal keeps its ghost outline (already .btn.ghost) and loses its inline
   margin-left:auto so the split, not the button, claims the free space. */
#view-pos > .toolbar #customerBar{order:1}
#view-pos > .toolbar #lotBar{order:2}
#view-pos > .toolbar #channelBar{order:3}
#view-pos > .toolbar #fundBar{order:4;margin-left:auto}
#view-pos > .toolbar #btnClearDeal{order:5;margin-left:8px!important}

/* ── 2 · POS page, add-button order ──────────────────────────────────────────────────
   §10: Inventory card, Cash, Manual card, Issue/Redeem credit, on BOTH sides.
   Shipped markup runs Inventory, Manual, Cash, Credit; flex order swaps the middle two
   without touching index.html. The ⚡ Scan button games.js injects immediately after the
   inventory-card button shares order 1, so source order keeps it exactly where it has
   always sat. Credit stays in the DOM and keeps order 4: body.feat-people-off hides it
   (app.css:68), and removing it would throw in cart-side/04-_vendPct.js and take the
   Manual card and Inventory card bindings down with it. */
#view-pos .li-add > *{order:5}
#view-pos .li-add #addMyInvCard,
#view-pos .li-add #addTheirCard,
#view-pos .li-add #qaScanMy,
#view-pos .li-add #qaScanTheir{order:1}
#view-pos .li-add #addMyCash,
#view-pos .li-add #addTheirCash{order:2}
#view-pos .li-add #addMyManual,
#view-pos .li-add #addTheirManual{order:3}
#view-pos .li-add #addMyCredit,
#view-pos .li-add #addTheirCredit{order:4}

/* ── 3 · Docked side panels (§12) ────────────────────────────────────────────────────
   Half the viewport wide, full height, resting against the outer wall of the side it
   covers and stopping dead at the midline.

   Gated at 781px, matching app.css:756 where .pos-grid stacks to one column. Below it
   there is no midline to dock against, so the shipped centred modal stands and every
   rule here is inert. posDockSide() reads null there too, so the click-outside close is
   off as well and phone behaviour is exactly what shipped. */
@media (min-width: 781px){

  /* Lighter than the shipped #000a, and no blur: the half you are actually filling has
     to stay readable behind the panel. pointer-events:none is §12's "cart rows on the
     lit side stay tappable" — the scrim paints but does not intercept. */
  :is(#modalRoot,#pickerHold).rd-dock .overlay{
    padding:0;
    background:#0006;
    backdrop-filter:none;
    align-items:stretch;
    pointer-events:none;
  }
  :is(#modalRoot,#pickerHold).rd-dock-right .overlay{justify-items:end}
  :is(#modalRoot,#pickerHold).rd-dock-left  .overlay{justify-items:start}

  :is(#modalRoot,#pickerHold).rd-dock .modal{
    pointer-events:auto;
    width:50%; max-width:none; min-width:0;   /* of the overlay: 50vw counted the scrollbar and the two panels overlapped by it */
    height:100vh; max-height:100vh;
    margin:0; border-radius:0;
    display:flex; flex-direction:column; overflow:hidden;
    animation:rdDockIn .26s cubic-bezier(.32,.72,.3,1);
  }
  :is(#modalRoot,#pickerHold).rd-dock-right .modal{border-right:0; border-radius:18px 0 0 18px; animation-name:rdDockInR}
  :is(#modalRoot,#pickerHold).rd-dock-left  .modal{border-left:0;  border-radius:0 18px 18px 0;  animation-name:rdDockInL}

  /* Slides in from its own wall (Ian 2026-09-15). A transform, so the panel arrives whole. */
  @keyframes rdDockInR{from{transform:translateX(100%);opacity:.6} to{transform:none;opacity:1}}
  @keyframes rdDockInL{from{transform:translateX(-100%);opacity:.6} to{transform:none;opacity:1}}
  @keyframes rdDockIn {from{opacity:0} to{opacity:1}}
  @media (prefers-reduced-motion: reduce){
    :is(#modalRoot,#pickerHold).rd-dock .modal{animation-duration:.01ms}
  }

  /* Full height only pays off if the list uses it. The body becomes the scroll column so
     a long editor still scrolls normally; the two picker lists take the leftover height
     and scroll inside themselves, which keeps their search field pinned at the top. You
     are adding card after card, and the box you type in must not scroll away. The
     50vh / 46vh caps are inline in the picker markup, hence !important. */
  :is(#modalRoot,#pickerHold).rd-dock .modal-body{
    flex:1 1 auto; min-height:0; overflow:auto;
    display:flex; flex-direction:column;
  }
  :is(#modalRoot,#pickerHold).rd-dock #ip_list,
  :is(#modalRoot,#pickerHold).rd-dock #cp_list{
    max-height:none!important;
    flex:1 1 auto; min-height:0;
  }
  /* 🖼 split view puts the list inside .pk-listcol, which is a plain block — the column
     has to carry the height down or the uncapped list just makes the body scroll. */
  :is(#modalRoot,#pickerHold).rd-dock .pk-split{flex:1 1 auto;min-height:0;align-items:stretch}
  :is(#modalRoot,#pickerHold).rd-dock .pk-listcol{display:flex;flex-direction:column;min-height:0}

  /* Which side the panel is feeding. The panel sits over the OTHER one, so say so. */
  :is(#modalRoot,#pickerHold).rd-dock .modal-head h3{display:flex;align-items:center;gap:9px}
  :is(#modalRoot,#pickerHold).rd-dock .rd-forside{
    font-size:11px; font-weight:600; letter-spacing:.02em;
    color:var(--accent); background:rgba(255,203,5,.12); border:1px solid rgba(255,203,5,.42);
    border-radius:999px; padding:2px 9px;
    font-family:'Segoe UI',Roboto,system-ui,sans-serif; text-transform:none;
    white-space:nowrap;
  }
}

/* ── 4 · Business ownership control (§16) ────────────────────────────────────────────
   A restyle of the SHIPPED control (public/js/pos/funding/03-fundChipsHTML.js), not a
   second one. Behaviour is untouched and stays as shipped: percentages appear at two
   owners and stay editable, rounding drift lands on the FIRST business, the total is
   live with a 0.5% tolerance, and the last ticked chip cannot be unticked.
   Dress only: bubbles, an inline % capsule, a proportional bar, and a running total that
   goes amber when the split does not reach 100. */
#fundChips > label{font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
#fundChips .fc-chip{
  border-radius:999px; padding:5px 13px; font-size:12.5px; font-weight:600;
  background:transparent; border:1px solid var(--line2); color:var(--muted);
}
#fundChips .fc-chip.primary{
  background:rgba(47,143,255,.14); border-color:var(--blue); color:#cfe0ff;
  box-shadow:none;
}
#fundChips .fc-chip .label-dot{width:9px;height:9px;border-radius:50%;display:inline-block}

/* The percentage rows become a second line of the same bubble, each with the % sitting
   in an inline capsule. The row markup carries inline display/gap/margin, so only the
   overrides that fight those carry !important; the pill itself is plain CSS. */
#fundChips .fc-pcts{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
#fundChips .fc-pcts > div{
  display:inline-flex!important;
  margin-bottom:0!important;
  gap:7px!important;
  align-items:center;
  border:1px solid var(--blue); background:rgba(47,143,255,.10);
  border-radius:999px; padding:3px 6px 3px 11px;
}
#fundChips .fc-pcts > div > label{flex:0 1 auto!important;font-size:12px!important;color:#cfe0ff}
#fundChips .fc-pct{
  width:56px!important; padding:2px 7px!important; border-radius:999px!important;
  font-size:11.5px!important; font-weight:700;
  background:rgba(0,0,0,.28)!important; border:1px solid rgba(47,143,255,.45)!important;
  color:var(--txt)!important;
}
#fundChips .fc-pct::-webkit-outer-spin-button,
#fundChips .fc-pct::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
#fundChips .fc-pcts > div > .muted{font-size:11px;padding-right:6px}

/* Proportional bar and running total, both full width under the bubbles. */
#fundChips .fc-bar{
  flex:0 0 100%; display:flex; height:5px; margin-top:9px;
  border-radius:999px; overflow:hidden; background:rgba(0,0,0,.30);
}
#fundChips .fc-bar span{height:100%}
#fundChips .fc-sum{flex:0 0 100%;margin-top:6px;font-weight:600}

/* ---- "RED RETIRED" (§10), scoped to the POS page ----
   The shipped .btn.primary is a red Poké-ball gradient; the prototype paints the same button
   blue and keeps red for danger only (.btn.danger, viewer-on). That is what §10's "red retired"
   actually asks for — it is not that no var(--red) appears in public/js/pos/, it is the primary
   button colour.

   Deliberately scoped to #view-pos and to the panels the POS page opens, NOT applied to
   .btn.primary globally. That rule paints Save on the card profile, Save in Settings, and every
   confirm button on screens the prototype never drew, and repainting all of them is a
   whole-app decision rather than part of this screen's port. Delete the scoping if Ian wants
   the blue everywhere. */
#view-pos .btn.primary,
:is(#modalRoot,#pickerHold):is(.rd-dock,.rd-pos) .btn.primary {
  background: var(--blue);
  border-color: var(--blue);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 3px 10px rgba(47, 143, 255, .28);
}
#view-pos .btn.primary:hover,
:is(#modalRoot,#pickerHold):is(.rd-dock,.rd-pos) .btn.primary:hover {
  filter: brightness(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 4px 16px rgba(47, 143, 255, .42);
  transform: translateY(-1px);
}
/* Destructive stays red, which is the half of §10 that was already right. */
#view-pos .btn.danger, :is(#modalRoot,#pickerHold).rd-dock .btn.danger { background: transparent; }

/* ── 5 · Side info button and popover ────────────────────────────────────────────────
   Replaces the two .sub subtitles under the side headings (public/index.html:269 and
   :282), which body.uxp has hidden permanently and which the integrator deletes. The
   explanation is read once, so it becomes something you press when you want it.

   The button rides inside .pos-side h4, which is already display:flex. That puts it
   outside #mySideItems / #theirSideItems, the only thing renderSide rewrites, so a cart
   re-render never touches it. Counter mode (.pos-side.cc) appends .cc-count to the same
   h4 with margin-left:auto, so the button drops its own auto margin there and sits to
   the right of the count instead of splitting the free space with it.

   .pos-side is overflow:hidden, so the bubble is pinned to the button's right edge and
   opens inward. It is absolutely positioned inside the button's own wrapper: it touches
   the button, nothing in the block reflows when it opens, and it never has to escape
   main's stacking context. */
.pos-side h4 .side-info{position:relative;display:inline-flex;flex:none;order:9;margin-left:auto}
.pos-side.cc h4 .side-info{margin-left:0}

.side-info-btn{
  width:26px;height:26px;padding:0;flex:none;
  display:grid;place-items:center;
  background:transparent;border:1px solid var(--line2);border-radius:50%;
  color:var(--muted);font-size:13px;font-weight:600;line-height:1;
  cursor:pointer;transition:.15s;
}
.side-info-btn:hover{color:var(--txt);border-color:var(--accent2)}
.side-info-btn:focus-visible{outline:2px solid var(--accent2);outline-offset:2px}
.side-info.open .side-info-btn{color:var(--txt);border-color:var(--accent2);background:var(--panel2)}

/* Closed is the default. .open is set by posSideInfoToggle, never by a style attribute. */
.side-info-pop{display:none}
.side-info.open .side-info-pop{
  display:block;position:absolute;top:100%;right:0;z-index:5;
  width:max-content;max-width:232px;
  background:var(--panel2);border:1px solid var(--line2);
  border-radius:10px;border-top-right-radius:0;
  padding:9px 11px;
  font-size:11.5px;line-height:1.45;font-weight:500;color:var(--muted);
  text-align:left;text-transform:none;letter-spacing:0;
  box-shadow:0 8px 22px rgba(0,0,0,.35);
}
.side-info-pop>div:first-child{color:var(--txt);font-weight:700}
.side-info-pop>div+div{margin-top:3px}

/* ── 6 · Empty side ──────────────────────────────────────────────────────────────────
   The prototype draws a dashed placeholder in each side; the shipped build cleared the
   container instead and let the blank column speak for itself. Ian: default to the empty
   state. One muted line, centred, with no action in it. The ＋ buttons directly below are
   the action, and repeating them here would just be a second row of the same offer. */
.side-empty{
  display:grid;place-items:center;
  min-height:96px;margin:2px 0 10px;padding:16px 12px;
  border:1px dashed var(--line2);border-radius:12px;
  color:var(--muted);font-size:12.5px;text-align:center;
}

/* Phone (Ian's iPhone, checked at 390px): the ⓘ becomes a real touch target, matching the
   bump app.css already gives .iconbtn and friends, and the bubble stops hanging off a
   26px anchor. 78vw keeps it inside the block at every phone width. */
@media(max-width:560px){
  .side-info-btn{width:44px;height:44px;font-size:16px}
  .side-info.open .side-info-pop{max-width:min(280px,78vw)}
  .side-empty{min-height:76px;padding:12px}
}

/* ═══ CART PICKER + PROFILE, SIDE BY SIDE (Ian 2026-09-15, js/pos/pickers/03-06) ═══════
   #pickerHold is the second root the picker parks in while its card's profile takes
   #modalRoot on the other wall. The dock rules above already match it through :is(). One
   scrim is enough for two panels, so the parked one paints none. Under 781px there is no
   second wall: the profile takes the screen and the parked picker waits, hidden, for ✕. */
/* :is(#modalRoot,#pickerHold).rd-dock .overlay above outranks a bare #pickerHold .overlay, and the
   parked picker sits later in the DOM than the profile, so its scrim was dimming the profile. */
#pickerHold.rd-dock .overlay{background:transparent;backdrop-filter:none}
/* Two panels meet at the midline edge to edge: no rounded corners and no shadow spilling
   across the seam while a picker is parked. */
#pickerHold.rd-dock .modal,
#modalRoot.rd-dock:has(~ #pickerHold.rd-dock) .modal{border-radius:0;box-shadow:none}
@media (max-width:780px){ #pickerHold{display:none} }
@media (min-width:781px){
  /* The profile at half width: a narrower rail, two stat tiles per row. */
  #modalRoot.rd-dock .modal.cardprofile .cp-wrap{grid-template-columns:150px minmax(0,1fr);gap:12px}
  #modalRoot.rd-dock .modal.cardprofile .cp-statrow{grid-template-columns:repeat(2,minmax(0,1fr))}
  #modalRoot.rd-dock .modal.cardprofile .cp-big{font-size:20px}
}

/* Toasts sit bottom-right, which is exactly where a right-docked panel keeps its Done button;
   an error toast stays until dismissed, so it blocked the panel (2026-09-22 break round). While
   a panel is docked right, toasts move to the bottom-left wall. */
@media (min-width: 781px){
  body:has(:is(#modalRoot,#pickerHold).rd-dock-right .modal) #notifyRoot{right:auto;left:18px}
}
