
/* ═══════════ V2 LAYOUT — RAIL OVERRIDES ═══════════
   Activated 2026-05-01. Restructures the page into:
      [ AI rail (left) | Canvas (center) | Sidebar rail (right) | Props panel (far right, slides) ]
   Pre-v2 the AI was a 680px card below the canvas (scrolled away while
   editing tiles) and the sidebar/My-Boards lived on the left. v2 swaps
   sidebar to right and promotes the AI to a persistent left rail.
   These rules ONLY apply when the AI helper carries the .ai-rail class
   (set in HTML), so the underlying inline-card styles still work if a
   future page reuses the .ai-helper component.
*/

/* AI helper as full-height left rail */
.ai-helper.ai-rail{
  width:var(--ai-rail-w);
  max-width:none;
  margin:0;
  border-radius:0;
  border:none;
  border-right:1px solid var(--border-light);
  height:calc(100vh - var(--topbar-h));
  flex-shrink:0;
  display:flex;
  flex-direction:column;
  background:var(--surface);
  box-shadow:none;
  overflow:hidden;
}
.ai-helper.ai-rail .ai-helper-toggle{
  border-radius:0;
  cursor:default; /* rail header is informational, not a collapse trigger */
  flex-shrink:0;
}
.ai-helper.ai-rail .ai-helper-body{
  display:flex;
  flex:1 1 auto;
  flex-direction:column;
  min-height:0;
  /* 2026-05-28 (Luke caught: "the left sidebar rail it's not sliding
     up or down — scrolling is not working"). .ai-helper.ai-rail above
     pins height to 100vh-topbar with overflow:hidden, so any content
     taller than the rail (which is now ALWAYS true once the profile
     hero + 17-item community accordion are both visible) gets clipped
     with no recourse. Add overflow-y:auto here so the body scrolls
     within the rail bounds instead. Touch-friendly scroll on iOS via
     -webkit-overflow-scrolling. */
  overflow-y:auto;
  overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
}
/* Always-on body even when .open is removed — the rail isn't collapsible */
.ai-helper.ai-rail:not(.open) .ai-helper-body{display:flex}
.ai-helper.ai-rail .ai-chat{
  flex:1 1 0;       /* basis 0 so chat doesn't claim natural height */
  min-height:80px;  /* keep at least one message visible */
  max-height:none;
  overflow-y:auto;
}
/* Suggestions cap to ~2 chip rows on the narrow 320px rail. Without this,
   6 wrapping chips can claim 4+ rows and push the input/Build button off
   the bottom of the viewport. Internal scroll keeps all chips reachable. */
.ai-helper.ai-rail .ai-suggestions{
  flex:0 0 auto;
  max-height:88px;
  overflow-y:auto;
  padding:0.5rem 0.6rem;
}
/* Input row (Build button) is sticky-bottom: even if a sibling overflows,
   the user can always reach Build. flex-shrink:0 + position:sticky belt
   AND suspenders so this never clips again. */
.ai-helper.ai-rail .ai-input-row{
  flex:0 0 auto;
  position:sticky;
  bottom:0;
  background:var(--bg);
  z-index:2;
}

/* Sidebar moved to right rail — flip the divider border */
.sidebar.sidebar-right{
  border-right:none;
  border-left:1px solid var(--border-light);
}

/* ═══════════ SIDEBAR v2.1 — ACCORDION + INDEPENDENT SCROLL ═══════════
   The right rail is height-bounded by .app-layout (calc(100vh - topbar)).
   Inside it, .sidebar-scroll is the only scroll context — so My Boards
   and Templates each cap their own height instead of pushing one another
   off-screen. Native <details> = no JS, free keyboard support, free a11y.
*/
.sidebar.sidebar-right .sidebar-scroll{
  flex:1 1 auto;
  overflow-y:auto;
  overflow-x:hidden;
  display:flex;
  flex-direction:column;
  gap:0.25rem;
  padding:0.5rem 0;
  min-height:0; /* lets flex children shrink + scroll inside flex parent */
}

.sidebar-acc{
  border-bottom:1px solid var(--border-light);
  background:transparent;
}
.sidebar-acc[open]{
  /* slight tint when open so the open section is obvious at a glance */
  background:var(--surface);
}
.sidebar-acc-summary{
  list-style:none;
  cursor:pointer;
  padding:0.7rem 1rem;
  font-size:0.72rem;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:0.08em;
  color:var(--ink-muted);
  display:flex;
  align-items:center;
  justify-content:space-between;
  user-select:none;
  transition:background var(--transition);
}
.sidebar-acc-summary::-webkit-details-marker{display:none}
.sidebar-acc-summary:hover{background:var(--surface-active);color:var(--ink)}
.sidebar-acc-summary:focus-visible{
  outline:2px solid var(--amber);
  outline-offset:-2px;
}
.sidebar-acc-chev{
  font-size:0.85rem;
  color:var(--ink-muted);
  transition:transform 0.18s ease;
  transform:rotate(-90deg);
}
.sidebar-acc[open] > .sidebar-acc-summary .sidebar-acc-chev{
  transform:rotate(0deg);
}
.sidebar-acc-body{
  padding:0.25rem 0 0.6rem;
  /* Bound the inner list so a long boards list doesn't push templates
     off the screen. The .sidebar-scroll above still scrolls the whole
     rail if accordion totals exceed viewport. */
  display:flex;
  flex-direction:column;
}
.sidebar-acc-body .sidebar-list{
  max-height:38vh;
}
.sidebar-acc-body .sidebar-templates{
  max-height:48vh;
  overflow-y:auto;
}

/* ═══════════ DEPLOY QR (Push-to-Devices accordion) ═══════════
   Persistent QR in the right rail so a parent can scan and start using
   the board on their phone with no account, no install. v2.2 2026-05-01. */
.sidebar-deploy{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:0.4rem;
  padding:0.4rem 0.75rem 0.6rem;
}
.sidebar-deploy-qr{
  /* Wave 16.B.14 (2026-05-11) — Luke flagged "my phone dont pick up
     any qr". Previous size was 148px frame / 132px canvas with
     ~3px modules for a 400-char URL — at the edge of what phone
     cameras can resolve. Bumped to 220px frame / 200px canvas so
     modules are ~5px each. Higher correctLevel (M not L) shipped
     in push-modal.js for redundancy. */
  width:220px;
  height:220px;
  background:#fff;
  border-radius:12px;
  padding:10px;
  box-shadow:var(--shadow-sm);
  display:flex;
  align-items:center;
  justify-content:center;
  /* QRCode library injects a <canvas> or <img> child; size them to fit */
}
.sidebar-deploy-qr canvas,
.sidebar-deploy-qr img,
.sidebar-deploy-qr svg{
  width:100%!important;
  height:100%!important;
  display:block;
}
.sidebar-deploy-qr.empty{
  background:var(--bg);
  color:var(--ink-muted);
  font-size:0.75rem;
  text-align:center;
  padding:14px;
}
/* 2026-06-10 (Luke spec item 6) — COMPACT too-big state. .empty kept
   the full 220×220 frame geometry and rendered a huge gray placeholder
   box with tiny "Board too big for QR" text inside, wasting the lower
   rail. .compact collapses the frame to an auto-height 2-line block:
   muted headline + trim hint with a real Push-to-Devices CTA (wired in
   push-modal.js refreshSidebarQR). .empty remains ONLY for the
   QR-render-failure path. Typography mirrors the neighboring
   .sidebar-deploy-caption / .sidebar-deploy-url rows. */
.sidebar-deploy-qr.compact{
  width:100%;
  height:auto;
  background:none;
  box-shadow:none;
  padding:0;
  flex-direction:column;
  gap:0.25rem;
}
.sidebar-deploy-too-big{
  font-size:0.72rem;
  font-weight:600;
  color:var(--ink-muted);
  text-align:center;
}
.sidebar-deploy-too-big-hint{
  font-size:0.72rem;
  color:var(--ink-soft);
  text-align:center;
  line-height:1.35;
}
.sidebar-deploy-push-link{
  background:none;
  border:none;
  padding:0;
  font:inherit;
  font-weight:700;
  color:var(--amber-dark);
  text-decoration:underline;
  cursor:pointer;
}
.sidebar-deploy-push-link:hover{color:var(--amber)}
.sidebar-deploy-caption{
  font-size:0.72rem;
  color:var(--ink-soft);
  text-align:center;
  line-height:1.35;
}
.sidebar-deploy-url{
  font-size:0.65rem;
  color:var(--ink-muted);
  font-family:ui-monospace,Menlo,Consolas,monospace;
  word-break:break-all;
  text-align:center;
  max-width:100%;
}
.sidebar-deploy-copy{
  margin-top:0.15rem;
  padding:0.4rem 0.85rem;
  border-radius:var(--radius-sm);
  background:var(--amber);
  color:#fff;
  font-size:0.72rem;
  font-weight:700;
  border:none;
  cursor:pointer;
  transition:background var(--transition);
}
.sidebar-deploy-copy:hover{background:var(--amber-dark)}
.sidebar-deploy-copy.copied{background:#2a7a3a}

/* ═══════════ A11Y SKIP LINK ═══════════
   Visible only when keyboard-focused. Was leaking visible at top-left
   on every page load (Luke screenshot 2026-05-01). The :not(:focus)
   guarantees screen readers still get it but sighted users don't see
   the leak. */
.a11y-skip{
  position:absolute;
  left:-9999px;
  top:auto;
  width:1px;
  height:1px;
  overflow:hidden;
  z-index:10000;
}
.a11y-skip:focus{
  left:0.5rem;
  top:0.5rem;
  width:auto;
  height:auto;
  padding:0.6rem 1rem;
  background:var(--ink);
  color:#fff;
  border-radius:var(--radius-sm);
  text-decoration:none;
  font-weight:600;
  outline:2px solid var(--amber);
}
