/* styles-playground.css — Phase C/D. */

/* === card preview (cardpreview.js) === */
/* The self-previewing strip on each gallery card: one decorative canvas
   (aria-hidden) painted by app/ui/cardpreview.js from the real simulator.
   :where() keeps these container defaults at zero specificity, so the
   gallery's own .pcard-preview rules always win on size and placement.
   The canvas is absolutely positioned so its pixel size never feeds back
   into the card's layout (the ResizeObserver re-fits it instead). */
:where(.pcard-preview) { position: relative; height: 56px; overflow: hidden; }
.pcard-preview > .pcard-preview-canvas {
  position: absolute; left: 0; top: 0;
  display: block; pointer-events: none;
}
/* === end card preview === */

/* === Playground gallery (ui/playground.js) ===
   Shelves per track, per-algorithm colour identity, Surprise me, and the
   Free build entry. Loaded after styles-v2/v3 in both frontends.

   Colour identity: every card, the run panel and its histogram carry one hue
   in --algo (set inline by playground.js from content/playground-catalog.js).
   Every shade below is derived from that one number. The lightness and
   saturation it is drawn at are per-theme (--pg-*), so the same hue reads as
   a deep ink on the light ground and a bright one on the dark ground. */

.playground{
  --pg-s:70%; --pg-l:45%; --pg-ink-l:30%; --pg-ink-s:60%;
  display:flex;flex-direction:column;gap:20px;
  padding:24px 20px;max-width:1120px;margin:0 auto;
  min-width:0;box-sizing:border-box;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme='light']) .playground{--pg-s:80%; --pg-l:62%; --pg-ink-l:77%; --pg-ink-s:80%}
}
:root[data-theme='dark'] .playground{--pg-s:80%; --pg-l:62%; --pg-ink-l:77%; --pg-ink-s:80%}

/* ------------------------------------------------------------- header */
.playground-bar{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.playground-exit{font-size:13px;padding:6px 14px}
.playground-title{display:flex;flex-direction:column;gap:2px;min-width:0}
.playground-eyebrow{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3);font-weight:600}
.playground-title b{font-size:19px;font-weight:700;color:var(--ink);letter-spacing:-.01em;line-height:1.25}
.playground-subtitle{font-size:13px;color:var(--ink-3);line-height:1.4}

/* ------------------------------------------------------------ actions */
.pg-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px}
.pg-action{
  display:flex;align-items:center;gap:14px;
  min-height:68px;padding:14px 16px;border-radius:12px;
  border:1.5px solid var(--rule);background:var(--surface);color:var(--ink);
  text-align:left;cursor:pointer;box-shadow:var(--elev-1);
  transition:border-color .16s,background .16s,transform .16s,box-shadow .16s;
}
.pg-action:hover{transform:translateY(-1px);border-color:var(--accent)}
.pg-action:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.pg-action-icon{font-size:26px;line-height:1;flex:none}
.pg-action-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.pg-action-text b{font-size:16px;font-weight:700}
.pg-action-text span{font-size:12.5px;color:var(--ink-3);line-height:1.35}
/* Surprise me is the page's primary action: the accent fill makes it the
   first thing the eye lands on. */
.pg-surprise{background:var(--accent);border-color:var(--accent);color:var(--on-accent);box-shadow:var(--glow),var(--elev-1)}
.pg-surprise:hover{background:var(--accent-2);border-color:var(--accent-2)}
.pg-surprise .pg-action-text span{color:var(--on-accent);opacity:.85}
.pg-free.active{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent)}

/* ----------------------------------------------------------- shelves */
.pg-shelves{display:flex;flex-direction:column;gap:24px;min-width:0}
.pg-shelf{min-width:0}
.pg-shelf-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px}
.pg-shelf-title{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0;
  font-size:17px;font-weight:700;color:var(--ink);letter-spacing:-.01em;
}
.pg-shelf-icon{
  display:inline-grid;place-items:center;width:28px;height:28px;border-radius:8px;font-size:15px;
  background:hsl(var(--algo) 70% 50% / .16);box-shadow:inset 0 0 0 1px hsl(var(--algo) 60% 50% / .3);
}
.pg-count{
  font-size:11.5px;font-weight:600;padding:2px 8px;border-radius:999px;
  color:hsl(var(--algo) var(--pg-ink-s) var(--pg-ink-l));background:hsl(var(--algo) 70% 52% / .14);
}
.pg-shelf-nav{display:flex;gap:6px;flex:none}
.pg-nudge{
  width:30px;height:30px;min-height:30px;padding:0;border-radius:999px;
  border:1px solid var(--rule);background:var(--surface);color:var(--ink-2);
  font-size:18px;line-height:1;cursor:pointer;
}
.pg-nudge:hover:not(:disabled){border-color:hsl(var(--algo) var(--pg-s) var(--pg-l));color:var(--ink)}
.pg-nudge:disabled{opacity:.35;cursor:default}
@media (pointer: coarse){ .pg-shelf-nav{display:none} }

/* The row is the only thing that scrolls sideways — the page never does.
   Padding leaves room for the hover lift and the focus ring, which an
   overflow container would otherwise clip. */
.pg-row{
  position:relative;display:flex;gap:12px;
  overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-padding-inline:4px;
  padding:6px 4px 12px;margin:0 -4px;
  scrollbar-width:thin;scrollbar-color:hsl(var(--algo) 40% 50% / .45) transparent;
}
@media (prefers-reduced-motion: no-preference){ .pg-row{scroll-behavior:smooth} }
.pg-row > .playground-card{flex:0 0 228px;scroll-snap-align:start}
@media (max-width: 480px){ .pg-row > .playground-card{flex-basis:76%} }

/* --------------------------------------------------------------- card */
.playground-card{
  --algo:250;
  position:relative;overflow:hidden;
  display:flex;flex-direction:column;align-items:stretch;gap:6px;
  padding:0 0 12px;border-radius:12px;
  border:1.5px solid var(--rule);background:var(--surface);color:var(--ink);
  text-align:left;cursor:pointer;
  transition:border-color .16s,background .16s,transform .16s,box-shadow .16s;
}
/* The hue as a top rule: visible at rest, so a shelf reads as a set of
   distinct things before anything is hovered or picked. */
.playground-card::before{
  content:'';position:absolute;inset:0 0 auto 0;height:3px;z-index:1;
  background:hsl(var(--algo) var(--pg-s) var(--pg-l));
  opacity:.85;transition:opacity .16s;
}
.playground-card:hover{
  border-color:hsl(var(--algo) var(--pg-s) var(--pg-l));
  background:hsl(var(--algo) 70% 52% / .07);
  transform:translateY(-2px);
  box-shadow:0 6px 18px hsl(var(--algo) 60% 30% / .16);
}
.playground-card:focus-visible{outline:2px solid hsl(var(--algo) var(--pg-s) var(--pg-l));outline-offset:2px}
.playground-card.active{
  border-color:hsl(var(--algo) var(--pg-s) var(--pg-l));
  background:hsl(var(--algo) 70% 52% / .11);
  box-shadow:0 0 0 2px hsl(var(--algo) 70% 50% / .55);
}
.playground-card.active::before{opacity:1}
/* The self-preview strip: full card width, tinted even before (or without)
   its animation, so a card at rest still carries its colour. */
.pcard-preview{
  display:block;width:100%;height:56px;flex:none;
  background:linear-gradient(180deg,hsl(var(--algo) 70% 50% / .05),hsl(var(--algo) 70% 50% / .13));
  border-bottom:1px solid hsl(var(--algo) 60% 50% / .2);
}
.pg-card-top{display:flex;align-items:center;gap:8px;padding:4px 12px 0;min-width:0}
.playground-card-icon{font-size:20px;line-height:1;flex:none}
.playground-card-title{font-size:15px;font-weight:750;color:var(--ink);line-height:1.25;letter-spacing:-.01em;min-width:0}
/* A fixed two-line slot: long hooks wrap and clamp, short ones still leave
   every card's chip row on the same baseline. */
.playground-card-tag{
  padding:0 12px;
  font-size:12px;color:var(--ink-2);line-height:1.35;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;
  overflow:hidden;min-height:2.7em;
}
.playground-card-meta{display:flex;flex-wrap:wrap;gap:5px;margin-top:2px;padding:0 12px}
.playground-chip{
  font-size:10.5px;font-weight:600;letter-spacing:.01em;
  padding:2px 7px;border-radius:999px;
  color:hsl(var(--algo) var(--pg-ink-s) var(--pg-ink-l));background:hsl(var(--algo) 70% 52% / .15);
}

/* ---------------------------------------------------------- run panel */
.playground-run{
  background:var(--surface);border:2px solid var(--rule);border-radius:12px;
  padding:18px;box-shadow:var(--elev-1);min-width:0;
  scroll-margin-top:calc(var(--topbar-h, 56px) + 12px);
}
.playground-run.empty{background:transparent;border-style:dashed;box-shadow:none;padding:6px 18px}
.playground-run.tinted{
  border-color:hsl(var(--algo) var(--pg-s) var(--pg-l) / .75);
  box-shadow:inset 0 4px 0 -1px hsl(var(--algo) var(--pg-s) var(--pg-l)),var(--elev-1);
}
.playground-run.pg-free-run{border-color:color-mix(in srgb,var(--accent) 60%,var(--rule))}
/* A new circuit arriving: one ring in its own hue, once — it says "this
   panel just changed to that card", which a static swap does not. */
.playground-run.pg-arrive{animation:pg-arrive .7s cubic-bezier(.22,.9,.28,1)}
@keyframes pg-arrive{
  from{box-shadow:0 0 0 0 hsl(var(--algo, 230) 80% 55% / .55)}
  to{box-shadow:0 0 0 16px hsl(var(--algo, 230) 80% 55% / 0)}
}
.playground-run-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.playground-run-name{display:flex;flex-direction:column;gap:2px;min-width:0}
.pg-run-from{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  color:hsl(var(--algo, 230) var(--pg-ink-s) var(--pg-ink-l));
}
.pg-free-run .pg-run-from{color:var(--accent)}
.pg-surprise-tag{
  text-transform:none;letter-spacing:0;font-weight:600;font-size:11px;
  padding:1px 8px;border-radius:999px;background:hsl(var(--algo) 70% 52% / .15);
}
.pg-run-heading{margin:0;font-size:20px;font-weight:750;color:var(--ink);letter-spacing:-.015em;line-height:1.2}
/* A programmatic focus target (tabindex=-1) after Surprise me / Free build,
   not a control: no ring, which otherwise boxed the title and clipped the
   subtitle under it. */
.playground .pg-run-heading:focus,.playground .pg-run-heading:focus-visible,
.playground .pg-free-host:focus,.playground .pg-free-host:focus-visible{outline:none;box-shadow:none}
.playground-run-sub{font-size:12.5px;color:var(--ink-3);font-weight:500;line-height:1.35}
.playground-nudge{color:var(--ink-3);font-size:14px;text-align:center;padding:14px 0;margin:0}
.pg-story{
  margin:0 0 16px;padding:10px 14px;border-radius:8px;
  border-left:3px solid hsl(var(--algo) var(--pg-s) var(--pg-l));
  background:hsl(var(--algo) 70% 52% / .07);
}
.pg-hook{margin:0 0 6px;font-size:15px;font-weight:600;color:var(--ink);line-height:1.45}
.playground-run-blurb{font-size:14px;color:var(--ink-2);margin:0;line-height:1.5}
.pg-takeaway-label{color:hsl(var(--algo) var(--pg-ink-s) var(--pg-ink-l));font-weight:700}
.pg-free-host{min-height:120px;min-width:0}

/* Histogram bars in the borrowed workbench take the loaded circuit's hue,
   so Grover's bars are amber and Shor's violet. Scoped to the run panel:
   the same #hist is back to the accent colour the moment it returns to
   Build. The impossible-outcome bar keeps its warning colour. */
.playground-run.tinted .hrow:not(.impossible) .hbar i{
  background:linear-gradient(90deg,
    hsl(var(--algo) var(--pg-s) var(--pg-l)),
    hsl(var(--algo) 85% calc(var(--pg-l) + 10%)));
}
.playground-run.tinted .hbar{background:hsl(var(--algo) 40% 50% / .13)}

/* ------------------------------------------------------ reduced motion */
@media (prefers-reduced-motion: reduce){
  .playground-run.pg-arrive{animation:none}
  .playground-card,.pg-action{transition:none}
  .playground-card:hover,.pg-action:hover{transform:none}
}
[data-reduced-motion='true'] .playground-run.pg-arrive{animation:none}
[data-reduced-motion='true'] .playground-card,
[data-reduced-motion='true'] .pg-action{transition:none}
[data-reduced-motion='true'] .playground-card:hover,
[data-reduced-motion='true'] .pg-action:hover{transform:none}
[data-reduced-motion='true'] .pg-row{scroll-behavior:auto}

/* --------------------------------------------------------- narrow */
@media (max-width: 480px){
  .playground{padding:16px 12px;gap:16px}
  .playground-run{padding:14px 12px}
  .pg-run-heading{font-size:18px}
}
/* === end Playground gallery === */
