/* ==========================================================================
   Sandbox: a small interactive playground inside a case study, laid out
   like Storybook. Shared by the KU color sandbox and the Luna arm panel
   sandbox; each page's own pieces (and its colors) live in ku.css and
   luna.css, and its behaviour in ku.js and luna.js on top of sandbox.js.
   ========================================================================== */

/* The sandbox ----------------------------------------------------------------
   Laid out like Storybook, in the page's own colors and one fixed height so
   nothing needs scrolling: a toolbar, the pairs from the system down the
   left, the live canvas, and a panel with tabs for the controls, the
   accessibility check and the code. Pass and fail are always written out,
   never shown by color alone. Below 860px it stacks. */
.sandbox {
  overflow: hidden;
  margin-top: 8px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
}
.sandbox__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding: 8px 10px 8px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
.sandbox__crumb {
  font-size: 0.875rem;
  color: var(--text);
}
.sandbox__crumb b {
  font-weight: 600;
  color: var(--ink);
}
.sandbox__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.sandbox__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.sandbox__btn:hover {
  border-color: var(--ink);
}
.sandbox__btn:focus-visible,
.sandbox__tabs [role="tab"]:focus-visible,
.play__preset:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
.sandbox__btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* the holding box toggle, drawn as a switch */
.sandbox__switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 0 6px 0 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.sandbox__switch input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.sandbox__switch span {
  position: relative;
  width: 32px;
  height: 18px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 30%, var(--bg));
  transition: background 0.15s ease;
}
.sandbox__switch span::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  transition: translate 0.15s ease;
}
.sandbox__switch input:checked + span {
  background: var(--accent);
}
.sandbox__switch input:checked + span::after {
  translate: 14px 0;
}
.sandbox__switch input:focus-visible + span {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}

.sandbox__body {
  display: grid;
  grid-template-columns: 196px minmax(0, 1fr);
  height: 540px;
}
.sandbox__side {
  overflow-y: auto;
  padding: 10px 8px;
  border-right: 1px solid var(--line);
  background: var(--bg);
}
.sandbox__side ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sandbox .sandbox__group {
  padding: 8px 8px 4px;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
}
.sandbox .sandbox__group:first-child {
  padding-top: 2px;
}
.play__preset {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 36px;
  padding: 4px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.8125rem;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}
.play__preset:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}
.play__preset[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-text);
  font-weight: 600;
}
.play__aa {
  display: grid;
  flex: none;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.12);
  font-size: 0.8125rem;
  font-weight: 700;
}

.sandbox__main {
  display: grid;
  grid-template-rows: minmax(0, 1fr) 214px;
  min-width: 0;
}
/* the canvas: a dotted backdrop, the preview centred on it */
.sandbox__canvas {
  display: grid;
  place-items: center;
  padding: 18px;
  overflow: hidden;
  background-color: var(--surface);
  background-image: radial-gradient(color-mix(in srgb, var(--ink) 14%, transparent) 1px, transparent 1px);
  background-size: 16px 16px;
}

/* the panel under the canvas, with its tabs */
.sandbox__panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.sandbox__tabs {
  display: flex;
  gap: 4px;
  padding: 0 10px;
  border-bottom: 1px solid var(--line);
}
.sandbox__tabs [role="tab"] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 10px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.sandbox__tabs [role="tab"][aria-selected="true"] {
  border-bottom-color: var(--accent);
  color: var(--ink);
}
.sandbox__badge {
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.sandbox__badge.is-pass {
  background: color-mix(in srgb, var(--ok-text) 16%, transparent);
  color: var(--ok-text);
}
.sandbox__badge.is-fail {
  background: color-mix(in srgb, var(--bad-text) 14%, transparent);
  color: var(--bad-text);
}
.sandbox__pane {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 16px 12px;
}
.sandbox__pane[hidden] {
  display: none;
}
.sandbox__row {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 6px 0;
}
.sandbox__row + .sandbox__row {
  border-top: 1px solid var(--line);
}
.sandbox__label {
  display: flex;
  flex-direction: column;
  font-size: 0.8125rem;
  font-weight: 600;
}
.play__picked {
  font-size: 0.8125rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.sandbox__code {
  position: relative;
}
.sandbox__code .code {
  margin: 0;
  padding: 12px 14px;
}
.sandbox__code .sandbox__btn {
  position: absolute;
  top: 18px;
  right: 24px;
}

@media (max-width: 860px) {
  .sandbox__body {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
  }
  /* the pairs become one row that scrolls sideways */
  .sandbox__side {
    display: flex;
    align-items: center;
    gap: 4px;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .sandbox__side ul {
    flex-direction: row;
  }
  .sandbox .sandbox__group {
    padding: 0 4px 0 8px;
  }
  .play__preset {
    white-space: nowrap;
  }
  .sandbox__main {
    grid-template-rows: auto auto;
  }
  .sandbox__canvas {
    padding: 16px 12px;
  }
  .sandbox__row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sandbox__switch span,
  .sandbox__switch span::after {
    transition: none;
  }
}

/* The sandbox stands out from the story around it, in its own look: a
   border whose colors turn once as it arrives, a soft wash behind it, an
   "Interactive" tag, its own heading and a strip of colors. Each page sets
   the colors (--sb-ring, --sb-wash, --sb-shadow, --sb-glow): KU uses its
   brand palette, Luna its arm colors. When it scrolls into view
   (sandbox.js adds .is-in) it rises into place, the border turns and the
   strip fills in, then the page's demo runs until the visitor touches it.
   Without JS, or with reduced motion, it simply sits there. */
@property --sb-turn {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
.sandbox-wrap {
  --sb-ring: var(--accent), var(--accent);
  --sb-wash: linear-gradient(transparent, transparent);
  --sb-shadow: rgb(0 0 0 / 0.25);
  --sb-glow: var(--accent);
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: 36px;
  padding: clamp(18px, 2.6vw, 30px);
  border: 3px solid transparent;
  border-radius: 24px;
  background:
    var(--sb-wash) padding-box,
    linear-gradient(var(--bg), var(--bg)) padding-box,
    conic-gradient(from var(--sb-turn), var(--sb-ring)) border-box;
  box-shadow: 0 30px 60px -32px var(--sb-shadow);
  scroll-margin-top: calc(var(--bar-h, 60px) + 24px);
}
.sandbox-wrap .sandbox {
  margin-top: 0;
}
.sandbox-wrap__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.cp-main .sandbox-wrap .sandbox-wrap__tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px 4px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.sandbox-wrap__tag svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}
.cp-main .sandbox-wrap .sandbox-wrap__title {
  font-family: var(--heading-font);
  font-size: clamp(1.75rem, 1.3rem + 1.4vw, 2.4rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink);
}
.cp-main .sandbox-wrap .sandbox-wrap__text {
  max-width: 40em;
  color: var(--text);
}
/* all 17 brand colors in one strip */
.sandbox-wrap__strip {
  display: flex;
  height: 10px;
  overflow: hidden;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.08);
}
.sandbox-wrap__strip i {
  flex: 1;
  background: var(--c);
}

/* the entrance, only when ku.js has set it up (.js-reveal) */
.sandbox-wrap.js-reveal {
  opacity: 0;
  translate: 0 56px;
  scale: 0.96;
  transition: opacity 0.6s ease, translate 0.9s cubic-bezier(0.2, 0.7, 0.2, 1), scale 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.sandbox-wrap.js-reveal .sandbox-wrap__strip i {
  scale: 1 0;
  transition: scale 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: calc(0.45s + var(--i) * 0.04s);
}
.sandbox-wrap.js-reveal.is-in {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  animation: sb-turn 1.8s 0.3s cubic-bezier(0.4, 0, 0.2, 1) both, sb-glow 2.2s 0.6s ease-out both;
}
.sandbox-wrap.js-reveal.is-in .sandbox-wrap__strip i {
  scale: 1 1;
}
@keyframes sb-turn {
  from { --sb-turn: 0deg; }
  to { --sb-turn: 360deg; }
}
@keyframes sb-glow {
  0% { box-shadow: 0 30px 60px -32px var(--sb-shadow), 0 0 0 0 color-mix(in srgb, var(--sb-glow) 55%, transparent); }
  60% { box-shadow: 0 30px 60px -32px var(--sb-shadow), 0 0 0 18px transparent; }
  100% { box-shadow: 0 30px 60px -32px var(--sb-shadow), 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .sandbox-wrap.js-reveal,
  .sandbox-wrap.js-reveal .sandbox-wrap__strip i {
    opacity: 1;
    translate: none;
    scale: none;
    transition: none;
    animation: none;
  }
}

/* The sandbox speaks in a technical, terminal-like face (JetBrains Mono),
   so it feels like a tool rather than part of the story. Anything marked
   data-real keeps a plain sans: it stands in for the real product (KU's
   Brand Center page, Luna's console). The heading gets a prompt and a
   blinking cursor (still for reduced motion). */
.sandbox-wrap {
  --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}
.cp-main .sandbox-wrap,
.cp-main .sandbox-wrap :is(p, h4, button, span, b, small, li, label, code, pre) {
  font-family: var(--mono);
  letter-spacing: -0.01em;
}
.cp-main .sandbox-wrap [data-real],
.cp-main .sandbox-wrap [data-real] * {
  font-family: var(--body-font);
  letter-spacing: normal;
}
.cp-main .sandbox-wrap .sandbox-wrap__title {
  font-family: var(--mono);
  font-size: clamp(1.4rem, 1.05rem + 1.1vw, 1.95rem);
  font-weight: 700;
  letter-spacing: -0.03em;
}
.sandbox-wrap__title::before {
  content: "> ";
  color: var(--accent-text);
}
.sandbox-wrap__title::after {
  content: "";
  display: inline-block;
  width: 0.55em;
  height: 1em;
  margin-left: 0.15em;
  vertical-align: -0.12em;
  background: var(--accent);
  animation: sb-caret 1.1s steps(1) infinite;
}
@keyframes sb-caret {
  50% { opacity: 0; }
}
.cp-main .sandbox-wrap .sandbox-wrap__text {
  font-size: 0.9375rem;
  line-height: 1.6;
}
.cp-main .sandbox-wrap .sandbox-wrap__tag {
  letter-spacing: 0.08em;
}
.cp-main .sandbox-wrap .sandbox__crumb {
  font-size: 0.8125rem;
}
@media (prefers-reduced-motion: reduce) {
  .sandbox-wrap__title::after {
    animation: none;
  }
}
