* { box-sizing: border-box; }

/* STRUCTURAL GUARD (2026-06-29): the HTML [hidden] attribute means "not
   rendered", but the UA rule `[hidden]{display:none}` is specificity 0,1,0 and
   ANY class that sets `display` silently outranks it — exactly how a "hidden"
   styled overlay (.fw-player__error{display:grid}) became an invisible click-trap
   over the creation player. Make [hidden] un-overridable everywhere so
   `el.hidden = true` always = gone, regardless of other display rules. Replaces
   per-element fixes (e.g. the old .fw-player__error[hidden]). app.css is the
   universal app base (parent/landing/admin/index/power all load it), so this
   applies site-wide — it also fixes a latent case where landing's hidden
   waitlist form rendered visible on load. Guarded by creation-render.test.ts +
   creation-clickable.e2e.ts. */
[hidden] { display: none !important; }

/* Body type/ink/background are owned by the design-system base layer
   (design-system/tokens/base.css: --font-body Nunito, --text-strong,
   --surface-canvas). Don't re-declare them here — a later equal-specificity
   body rule used to silently override the tokens with a system font + #222. */
body { margin: 0; }

#banner { display: flex; align-items: center; gap: 16px; padding: 10px 16px; background: #1f2937; color: white; font-size: 14px; }
#banner-stats { flex: 1; color: #cbd5e1; font-family: ui-monospace, monospace; font-size: 12px; }
#banner button, #banner a { color: white; background: transparent; border: 1px solid #6b7280; padding: 4px 10px; border-radius: 6px; font-size: 13px; cursor: pointer; text-decoration: none; }
#banner button:hover, #banner a:hover { background: #374151; }

#main { display: grid; grid-template-columns: 1fr 1fr; height: calc(100vh - 44px); }

#chat-section { display: flex; flex-direction: column; border-right: 1px solid #e5e7eb; min-width: 0; min-height: 0; }
#mode-toggle { padding: 10px 14px; background: #fff3cd; border-bottom: 1px solid #f0e3c7; font-size: 13px; display: flex; gap: 16px; }
#mode-toggle label { cursor: pointer; }
#chat-log { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 14px; }
.msg { padding: 10px 14px; border-radius: 10px; max-width: 92%; word-wrap: break-word; }
.msg.user { background: #dbeafe; align-self: flex-end; }
.msg.assistant { background: #f0fdf4; align-self: flex-start; }
.msg .role { font-size: 11px; color: #475569; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
.msg .body { font-size: 15px; }
.debug { font-family: ui-monospace, monospace; font-size: 11px; background: #f8fafc; border: 1px dashed #cbd5e1; border-radius: 6px; padding: 8px 10px; color: #475569; line-height: 1.4; align-self: flex-end; max-width: 92%; }
.debug-line { white-space: pre; }

#composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid #e5e7eb; background: #f9fafb; }
#message-input { flex: 1; font-family: inherit; font-size: 15px; padding: 8px 10px; border: 1px solid #cbd5e1; border-radius: 8px; resize: vertical; }
#send-btn { padding: 0 18px; font-size: 15px; border: 0; border-radius: 8px; background: #2563eb; color: white; cursor: pointer; }
#send-btn:disabled { background: #94a3b8; cursor: wait; }

#preview-section { display: flex; flex-direction: column; min-width: 0; }
#snapshot-strip { padding: 10px 14px; background: #f1f5f9; border-bottom: 1px solid #e5e7eb; font-family: ui-monospace, monospace; font-size: 13px; display: flex; gap: 6px; flex-wrap: wrap; }
.turn-chip { display: inline-block; padding: 2px 8px; border-radius: 4px; background: #fff; border: 1px solid #cbd5e1; cursor: pointer; }
.turn-chip.current { background: #2563eb; color: white; border-color: #1d4ed8; font-weight: bold; }
#preview-frame { flex: 1; border: 0; background: white; }

#events-pane { flex-shrink: 0; border-top: 1px solid #e5e7eb; background: #fff; }
#events-toggle { width: 100%; text-align: left; padding: 8px 14px; background: #f9fafb; border: 0; cursor: pointer; font-family: ui-monospace, monospace; font-size: 12px; }
#events-body { margin: 0; padding: 12px 14px; font-family: ui-monospace, monospace; font-size: 11px; max-height: 280px; overflow: auto; background: #1e293b; color: #e2e8f0; }
.debug { margin-top: -6px; }
.debug-label { color: #94a3b8; }
.debug-value { color: #1e293b; }
.debug-error { color: #b91c1c; }
.debug-events-link { color: #2563eb; cursor: pointer; text-decoration: underline; margin-top: 4px; display: inline-block; }
.debug-handoff-hdr { color: #b45309; margin-top: 6px; font-weight: bold; }
.debug-handoff { color: #92400e; background: #fffbeb; }

/* ── Power-builder transcript — Claude-Code-like, light, ONE type scale ──
   All tokens scoped to .pu-thread so guardian/global chat styles are untouched. */
.pu-thread {
  --pu-fg: #1f2937;       /* primary text */
  --pu-dim: #5b6472;      /* interim narration */
  --pu-faint: #9ca3af;    /* labels, args, idle meta */
  --pu-line: #e5e7eb;     /* hairlines */
  --pu-accent: #b45309;   /* tool / working amber (matches app handoff accent) */
  --pu-ok: #15803d;
  --pu-err: #b91c1c;
  --pu-link: #2563eb;
  --pu-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --pu-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  align-self: stretch;
  max-width: 100%;
  background: #fff;
  border: 1px solid var(--pu-line);
  border-radius: 10px;
  padding: 12px 14px;
  color: var(--pu-fg);
  font-family: var(--pu-sans);
  font-size: 14px;
  line-height: 1.6;
}
.pu-thread .role { font-size: 11px; color: var(--pu-faint); text-transform: uppercase; letter-spacing: .06em; margin-bottom: 8px; }

.pu-step { animation: pu-in .14s ease both; }
@keyframes pu-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
@keyframes pu-pulse { 50% { opacity: .3; } }

/* tool line: subtle, scannable, secondary — like Claude Code's tool use rows */
.pu-tool {
  font-family: var(--pu-mono);
  font-size: 12.5px;
  line-height: 1.5;
  display: flex; gap: 7px; align-items: baseline;
  padding: 3px 0;
  color: var(--pu-dim);
}
.pu-tool .pu-dot { color: var(--pu-accent); flex: none; font-size: 10px; }
.pu-tool.busy .pu-dot { animation: pu-pulse 1s ease-in-out infinite; }
.pu-tool .pu-name { color: var(--pu-fg); }
.pu-tool .pu-arg { color: var(--pu-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pu-tool .pu-state { margin-left: auto; flex: none; }
.pu-tool.ok .pu-state { color: var(--pu-ok); }
.pu-tool.err .pu-state { color: var(--pu-err); }

/* interim narration: VISIBLE as it streams, one notch dimmer than the answer */
.pu-say { color: var(--pu-dim); margin: 6px 0; }

/* final answer: the primary content — same light surface, hairline separator */
.pu-answer { color: var(--pu-fg); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--pu-line); }

/* build confirmation — native to the transcript (not a separate chat bubble).
   Rendered as an <a> in kid+power live + reload paths, so it's always a
   clickable affordance; a plain <div> remains a graceful fallback. */
.pu-built { font-family: var(--pu-mono); font-size: 12.5px; color: var(--pu-ok); margin-top: 8px; }
a.pu-built { display: inline-block; text-decoration: none; cursor: pointer; transition: opacity .12s; }
a.pu-built:hover { text-decoration: underline; opacity: .85; }
a.pu-built:focus-visible { outline: 2px solid var(--pu-ok); outline-offset: 2px; border-radius: 2px; }

/* Try-again chip — sibling of .pu-built, rendered when a build failed (2
   attempts exhausted). Click re-emits a "yes" so the guardian's pending-
   build state moves forward into another build attempt. */
.pu-try-again {
  display: inline-block;
  margin-top: 8px;
  padding: 6px 12px;
  font-family: var(--pu-mono);
  font-size: 12.5px;
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fcd34d;
  border-radius: 999px;
  cursor: pointer;
  transition: background .15s, transform .05s;
}
.pu-try-again:hover { background: #fde68a; }
.pu-try-again:active { transform: translateY(1px); }
.pu-try-again:focus-visible { outline: 2px solid #b45309; outline-offset: 2px; }

/* Built CARD (kid surface) — mirror of mobile ChatBubble builtCard
   (ChatBubble.tsx styles.builtCard/builtLive/builtTitle/playChip). Replaces
   the inline .pu-built link on the KID surface only; .pu-built stays for
   parent/power. */
.pu-built-card {
  display: flex; flex-direction: column; gap: 10px;
  align-self: flex-start; max-width: 84%;
  margin-top: 10px; padding: 13px 15px;
  background: var(--color-primary-soft);
  border: 1.5px solid var(--color-primary);
  border-radius: var(--radius-lg);
  text-decoration: none; cursor: pointer;
}
.pu-built-card__live { font-family: var(--font-mono, ui-monospace, monospace); font-size: 12.5px; line-height: 17px; color: var(--color-success); }
.pu-built-card__title { font-weight: 800; font-size: 15px; line-height: 21px; color: var(--color-primary-ink); }

/* live working indicator (mobile status line) — a bare centered "Working on
   it…" line rendered as a SIBLING of the thread (not nested in the bubble),
   removed on turn-end. As a sibling the .pu-thread-scoped --pu-* vars no longer
   resolve, so the fallbacks below carry the exact prior values (faint #9ca3af,
   amber dot #b45309). */
.pu-working { align-self: center; display: flex; align-items: center; gap: 8px; font-family: var(--pu-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); font-size: 12.5px; color: var(--pu-faint, #9ca3af); padding: 7px 0 2px; }
.pu-working .pu-spin { width: 7px; height: 7px; border-radius: 50%; background: var(--pu-accent, #b45309); animation: pu-pulse 1s ease-in-out infinite; }

/* markdown — light, within the ONE scale (scoped to the thread) */
.pu-thread .md > :first-child { margin-top: 0; }
.pu-thread .md > :last-child { margin-bottom: 0; }
.pu-thread .md h1, .pu-thread .md h2, .pu-thread .md h3 { font-size: 14px; font-weight: 650; margin: .85em 0 .3em; line-height: 1.3; }
.pu-thread .md h1 { font-size: 15px; }
.pu-thread .md p { margin: .5em 0; }
.pu-thread .md ul, .pu-thread .md ol { margin: .4em 0; padding-left: 1.35em; }
.pu-thread .md li { margin: .2em 0; }
.pu-thread .md code { font-family: var(--pu-mono); font-size: 12.5px; background: #f3f4f6; border: 1px solid var(--pu-line); border-radius: 4px; padding: .5px 4px; }
.pu-thread .md pre { background: #f6f7f9; border: 1px solid var(--pu-line); border-radius: 6px; padding: 9px 11px; overflow-x: auto; margin: .6em 0; }
.pu-thread .md pre code { background: none; border: 0; padding: 0; font-size: 12px; line-height: 1.5; }
.pu-thread .md a { color: var(--pu-link); }
.pu-thread .md strong { font-weight: 650; }

/* Parent co-pilot transcript */
/* .card.* (specificity 0,2,0) so these beat parent.html's inline .card { background:#fff } */
.card.msg-parent { background: #fef3c7; border-color: #fde68a; }
.card.msg-kid { background: #dbeafe; }
.card.msg-guardian { background: #f0fdf4; border-color: #dcfce7; }
.card.msg-detail { font-family: ui-monospace, monospace; font-size: 12px; color: #475569; background: #eef2f7; }

/* Kid sees the grown-up's co-pilot messages (async) */
.grownup-bubble { background: #fef3c7 !important; }
.grownup-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #92400e; margin-bottom: 2px; }

/* ── Parent overview: kid tabs + gallery cards (ported from the kid SPA gallery) ── */
.kid-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0 20px; }
.kid-tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 999px; border: 1.5px solid #e2e8f0;
  background: #fff; color: #475569; font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.kid-tab:hover { border-color: #c4b5fd; }
.kid-tab.active { background: #7c3aed; color: #fff; border-color: #7c3aed; }
.kid-tab-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: rgba(15, 23, 42, .08); font-size: 12px; font-weight: 700;
}
.kid-tab.active .kid-tab-count { background: rgba(255, 255, 255, .25); }

.gallery-sentinel { height: 1px; }
/* The kid Recent-work card (.gallery-card / .card-*) is defined ONCE, in the
   index.html inline <style> (the only surface that renders it). The duplicate
   copy that used to live here was fully shadowed by that inline block (and no
   other surface renders .gallery-card) — removed to keep a single source. */


/* ── Chat / Build view (creation-scoped) — matches the kid chat ── */
.chat-back { background: transparent; border: 0; color: #6b7280; font: inherit; font-size: 14px; cursor: pointer; padding: 4px 0; }
.chat-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 6px 0 10px; }
.chat-head h1 { margin: 0; }
.chat-badge { font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px; }
.chat-badge.chat { background: #f5f3ff; color: #5b21b6; }
.chat-badge.build { background: #fff7ed; color: #9a3412; border: 1px solid #fed7aa; }

/* Details = a real toggle switch (not a dropdown) */
.chat-detail { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: #475569; margin-bottom: 12px; cursor: pointer; user-select: none; }
.chat-switch { position: relative; width: 38px; height: 22px; flex: none; }
.chat-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.chat-switch .track { position: absolute; inset: 0; background: #cbd5e1; border-radius: 999px; transition: background .15s ease; }
.chat-switch .track::before { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: #fff; border-radius: 50%; transition: transform .15s ease; box-shadow: 0 1px 2px rgba(0, 0, 0, .2); }
.chat-switch input:checked + .track { background: #7c3aed; }
.chat-switch input:checked + .track::before { transform: translateX(16px); }

/* The grown-up chat's transcript box + composer layout now live in portal.css
   (.pl-gchat__col .pl-gchat__log / .pl-gchat__composer), shared by class with
   the kid chat. The old id-scoped #tx-messages-col / #tx-composer rules that
   lived here were a legacy port of the kid SPA chat: #tx-input / #tx-send /
   #tx-messages-col are absent from every current template, and the surviving
   #tx-composer row-flex actively shrank the mounted composer. Removed. */

/* The .skel shimmer base, .pill-soft, .suggestion-chip, chip-in keyframe, and
   .user-bubble are now shared (one tokenized copy) in portal.css. Only the
   PARENT-specific chat-skeleton LAYOUT (scoped to #tx-messages) stays here. */
/* Chat skeleton — mirrors conversation rhythm: short right-aligned user
   bubble, then a taller assistant frame with a role bar + 3 line bars.
   SCOPED to #tx-messages: the kid surface (index.html) defines its own global
   .skel-chat / .skel-stagger with a different layout (flex:1, padding:14px);
   scoping here keeps the two surfaces' chat skeletons from shadowing each
   other so neither drifts when the other is edited. The shared .skel base +
   shimmer keyframe above stay global — they're identical across both. */
#tx-messages .skel-chat { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; }
#tx-messages .skel-user-bubble { align-self: flex-end; width: 42%; max-width: 280px; height: 36px; border-radius: 18px; }
#tx-messages .skel-assistant {
  align-self: stretch; background: #fff; border-radius: 14px; border: 1.5px solid #f3f4f6;
  box-shadow: 0 1px 2px rgba(31, 41, 55, .04); padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
}
#tx-messages .skel-assistant .skel-role { width: 64px; height: 10px; border-radius: 6px; }
#tx-messages .skel-assistant .skel-line { height: 12px; border-radius: 6px; }
#tx-messages .skel-assistant .skel-line.w-100 { width: 96%; }
#tx-messages .skel-assistant .skel-line.w-85  { width: 82%; }
#tx-messages .skel-assistant .skel-line.w-60  { width: 56%; }
#tx-messages .skel-stagger > *:nth-child(2) .skel { animation-delay: .08s; }
#tx-messages .skel-stagger > *:nth-child(3) .skel { animation-delay: .16s; }

/* Parent suggestion-row layout (the shared .suggestion-chip/.pill-soft visuals
   live in portal.css; chip-in keyframe too). The kid surface uses its own
   .suggestion-row padding + a --composer variant. */
.suggestion-row { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 0 2px; animation: chip-in .18s ease both; }
