/* ============================================================
   <preview-ui> — live code + render, single source of truth.

   A framed demo surface: a "stage" holding the live components on top
   (or beside) the same markup shown as escaped, highlighted, copyable
   HTML via a nested <code-ui>. The frame owns the chrome; the inner
   code-ui's own border/radius are flattened so the two panes read as
   one card.

   Two-block @scope per docs/specs/component-token-contract.md.
   ============================================================ */

@scope (preview-ui) {
  /* ── Block 1 — TOKENS ── */
  :where(:scope) {
    --preview-border:       1px solid var(--a-border-subtle);
    --preview-radius:       var(--a-radius-lg);
    --preview-render-bg:    var(--a-canvas-1);
    --preview-render-pad:   var(--a-space-6);
    --preview-render-gap:   var(--a-space-3);
    /* split column floor — below this the grid wraps to a single column
       (responsive without container-type; see ADR note in css-patterns). */
    --preview-split-min:    20rem;
  }

  /* ── Block 2 — BASE ── */
  :scope {
    display: block;
    border: var(--preview-border);
    border-radius: var(--preview-radius);
    overflow: hidden;
    background: var(--preview-render-bg);
  }

  /* Render stage — wraps live demo nodes; flex row so multiple sibling
     samples (e.g. button variants) sit on one line and wrap. overflow-x:auto is
     the last-resort affordance: a single unwrappable sample wider than even the
     full-width stage (a page-scale composite) scrolls instead of being clipped
     by the frame's overflow:hidden. Most demos fit (the component's overflow
     check stacks split→full-width first), so the scrollbar only appears when a
     demo is genuinely wider than the docs column. */
  /* Column flow is the default: each example stacks in DOM order and fills the
     stage width (align-items: stretch), so block-level demos (progress / bars /
     accordion / cards / pages …) read at full width without a per-component
     list. Text-flow atoms (button / badge / tag / …) opt back to content-width
     via align-self below. (bug-46 — replaces the old flex-row + :only-child
     block-flow hack, which only filled single-child demos.) */
  [data-preview-render] {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--preview-render-gap);
    padding: var(--preview-render-pad);
    background: var(--preview-render-bg);
    overflow-x: auto;
  }
  /* Lone text-flow atoms shouldn't span the whole stage — keep them
     content-width + leading-aligned (the ADR-0037 inline-display set). */
  [data-preview-render] > :is(button-ui, badge-ui, tag-ui, chip-ui, kbd-ui, icon-ui, swatch-ui, spinner-ui, switch-ui, avatar-ui) {
    align-self: start;
  }
  /* Form-field demos collapse to content-width as flex items in the render
     cell — a placeholder-only combobox shrank to a ~52px "Sel…" stub — so
     stretch form controls to the cell width with width:100%.
       • <field-ui> is a full-width form ROW: let it fill the whole stage,
         NO measure cap. The prior 28rem cap read as "not using available
         space" on wide single-block demos (bug-55 follow-up).
       • Bare atomic controls (input/select/…) keep the 28rem measure cap so
         a lone control doesn't sprawl into an unrealistic bar on a wide stage.
     Non-form demos (buttons, badges, etc.) are untouched — content-width. */
  [data-preview-render] field-ui {
    width: 100%;
  }
  [data-preview-render] > :is(input-ui, select-ui, combobox-ui, textarea-ui, tags-input-ui, color-input-ui) {
    width: 100%;
    max-width: 28rem;
  }
  /* Code pane — divider line between panes; flatten the nested code-ui
     chrome so the preview frame owns the outer border + radius. */
  [data-preview-code] {
    border-block-start: var(--preview-border);
    min-width: 0; /* allow the code-ui to shrink in split grid */
  }
  [data-preview-code] code-ui {
    display: block;
    --code-border: transparent;
    --code-radius: 0;
    --code-bg: var(--a-bg);
  }

  /* code-first — divider moves to the bottom of the (now-leading) code pane */
  :scope[code-first] [data-preview-code] {
    border-block-start: none;
    border-block-end: var(--preview-border);
  }

  /* Stacked layout — render above code. This is the BASE behaviour (above), so
     [layout="stack"] just names it explicitly: it's the opt-out from the
     side-by-side default that a bare <preview-ui> stamps on connect, and the
     value the docs pin onto wide self-framing demos (card / shell / table). */
  :scope[layout="stack"] {
    display: block;
  }

  /* ── Split layout — render + code side-by-side ──
     auto-fit grid collapses to one column under --preview-split-min with
     NO container-type (avoids the flex-child-collapse trap; see memory
     `container_name_convention`). When wrapped, the inter-pane divider
     reverts to the stacked top-border via the base rule above. */
  :scope[layout="split"] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--preview-split-min)), 1fr));
  }
  :scope[layout="split"] [data-preview-code] {
    border-block-start: none;
    border-inline-start: var(--preview-border);
    /* Stretch code-ui to the grid row height — the render side is often
       taller, so a short snippet would otherwise leave an empty code surface
       below it (same fill as rows mode). */
    display: grid;
  }
  :scope[layout="split"] [data-preview-code] code-ui {
    height: 100%;
  }
  /* Single-column fallback (grid wrapped): restore the horizontal divider.
     :scope[layout="split"] with one effective column → the code pane is on
     its own row, so the inline-start border reads as a stray left edge.
     Guard with a width media as a pragmatic floor. */
  @media (max-width: 32rem) {
    :scope[layout="split"] [data-preview-code] {
      border-inline-start: none;
      border-block-start: var(--preview-border);
    }
  }

  /* ══════════ rows mode — a gallery of [render | code] rows ══════════
     Each example is its own row: live render on the left, its source on the
     right, paired side-by-side (no all-renders-then-one-code-dump). Rows
     stack with a divider between them; each row is a 2-col grid that
     collapses to stacked on narrow widths. */
  :scope[rows] {
    display: block;
  }
  :scope[rows] [data-preview-row] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: stretch;
  }
  :scope[rows] [data-preview-row] + [data-preview-row] {
    border-block-start: var(--preview-border);
  }
  /* In rows mode the render/code panes butt horizontally — divider is the
     inline-start border on the code cell, not the stacked top-border. The
     cell is a grid so the nested code-ui STRETCHES to the row height (the
     render side is often taller), filling the dark code surface instead of
     leaving empty space below a short snippet. */
  :scope[rows] [data-preview-row] > [data-preview-code] {
    border-block-start: none;
    border-inline-start: var(--preview-border);
    display: grid;
  }
  :scope[rows] [data-preview-row] > [data-preview-code] code-ui {
    height: 100%;
  }
  /* Optional per-row caption pill (from [data-preview-label] on the render
     cell — attr() reads the element's OWN attribute). The render cell becomes
     a column so the pill sits above the live sample. */
  :scope[rows] [data-preview-render][data-preview-label] {
    flex-direction: column;
    align-items: flex-start;
  }
  :scope[rows] [data-preview-render][data-preview-label]::before {
    content: attr(data-preview-label);
    align-self: start;
    font-family: var(--a-font-family-mono);
    font-size: var(--a-ui-sm);
    color: var(--a-fg-muted);
    background: var(--a-bg-muted);
    padding: 0.125rem 0.375rem;
    margin-bottom: 0.5rem;
    border-radius: var(--a-radius-sm);
  }
  /* Narrow: collapse each row to stacked render-over-code. */
  @media (max-width: 40rem) {
    :scope[rows] [data-preview-row] {
      grid-template-columns: 1fr;
    }
    :scope[rows] [data-preview-row] > [data-preview-code] {
      border-inline-start: none;
      border-block-start: var(--preview-border);
    }
  }
  /* Content-driven fallback — a single row whose live sample is wider than the
     half-width cell gets [data-stack] from the component's overflow check, so it
     lays out render-over-code at full width (wide controls / composites). */
  :scope[rows] [data-preview-row][data-stack] {
    grid-template-columns: 1fr;
  }
  :scope[rows] [data-preview-row][data-stack] > [data-preview-code] {
    border-inline-start: none;
    border-block-start: var(--preview-border);
  }
}
