/* =========================================================
   Zomniverse — Programming Code Block Presentation
   PATCH 2026-08-28 | SHARED CSS FOUNDATION
   PATCH 2026-08-28b | ZOMNIVERSE VISUAL IDENTITY REFINEMENT
   PATCH 2026-08-28c | ZOMNIVERSE CODE CONSOLE (approved production)

   ROLE:
   - Canonical, mode-agnostic presentation for REAL programming-code
     blocks: the wrapper/header/label/button markup produced by the
     one shared enhancer, Scripts/learn/workers/learn-code-copy.js.
   - ONE unmistakable Zomniverse/ZAR AI code-block identity -- dark
     navy console, one accent rail, one syntax token palette (via
     Prism.js, see Scripts/vendor/prism/ and
     Scripts/shared/ui/zar_code_syntax_highlighter.js). Python, R,
     JavaScript, etc. all share the exact same container and colors.
     Adding a new language to COPYABLE_CODE_LANGUAGES requires ZERO
     changes to this file.
   - Does NOT own Markdown structure, Mermaid, image viewers, or any
     mode's document typography.

   APPROVED VISUAL SOURCE OF TRUTH:
   sandbox/mockups/programming-code-console/
   programming-code-console-syntax-highlighting.html (v2, approved).
   Values below are the sandbox's, translated to existing Zomniverse
   tokens wherever one already covers the need; see the report
   addendum ("Apply Approved Zomniverse Code Console") for the full
   per-value trace.

   CONTEXT IDENTITY -- CSS-DRIVEN, NOT JS-DRIVEN:
   The context dot/label (".zomniverse-code-context-dot/-label") are
   ALWAYS rendered by the enhancer, unconditionally, with generic
   "Code" text -- enhanceCodeBlocks() has no idea whether it is
   running for a Coding City answer. Whether the dot becomes visible
   and the label reads "ZAR Code" instead of "Code" is decided
   entirely here, by an ancestor selector on the EXISTING
   .zar-llm-insight--coding class (applied by
   shared/coding_city/templates.js::applyCodingStreamIdentity(),
   traced to land on the same .zar-llm-insight element that is
   passed as the enhancer's `container`). This was a deliberate
   choice over passing a JS-time flag: applyCodingStreamIdentity()
   can run AFTER the code-block enhancer already has, per
   guard_input_controller.js's actual call order -- a JS snapshot at
   enhancement time would be unreliable; a live CSS selector is not.
   The dot color/glow reuse the EXACT values already used in
   production for this exact purpose:
   Styles/modes/llm/llm_zar_ai_header.css:287-303
   (.zar-llm-insight--coding .zar-answer-mini-dot { background:
   #5eead4 } + its .zar-ai-icon-wrap glow). No standalone Coding City
   SVG/icon file exists anywhere in the project (searched image/,
   Scripts/, Styles/) -- this dot+glow pairing IS the real, current,
   live Coding City identity, faithfully reproduced, not invented.

   LANGUAGE LABEL -- TRUTH CONTRACT (unchanged from the prior patch):
   The visible label text is set by learn-code-copy.js from the
   block's own language-X class -- a plain declaration, e.g.
   "Python", never independently validated. This file never renders
   a checkmark, "Verified" text, shield icon, or any affordance that
   would imply validation.

   CLASS ARCHITECTURE:
   Targets the neutral shared classes the enhancer applies
   (.zomniverse-code-block / .zomniverse-code-header /
   .zomniverse-code-context(-dot/-label) / .zomniverse-code-language /
   .zomniverse-code-copy(-icon/-label)), added alongside the original
   Learn-named classes (.learn-code-block / .learn-code-copy, kept
   unchanged) -- see learn-code-copy.js's PATCH 2026-08-28c note.
   Styles/modes/learn/learn-code-copy.css keeps targeting the
   original Learn-named classes for its own color/border/radius
   THEME only; its old structural (position/top/right) rules were
   removed there because this file's real header row now owns
   structure for every consumer, Learn included -- see that file's
   own patch note for the exact reasoning.

   LOADING:
   Registered once via FrontendResourceManager::head(), present on
   every page without requiring Learn Mode to have been opened
   first.
========================================================= */

/* =========================================================
   WRAPPER -- DARK ZOMNIVERSE CONSOLE SURFACE

   Faint 24px technical grid reuses the exact technique already used
   for the ZAR loader panel surface
   (Styles/modes/zar/zar_loader_feedback.css:383-398): two low-opacity
   1px linear-gradient grid lines layered under the panel's own
   background gradient. Recolored for a dark surface; same spacing.
========================================================= */

.zomniverse-code-block {
  position: relative;
  box-sizing: border-box;
  margin: 0.85em 0 1.2em;

  border-radius: 0.85rem;
  border: 1px solid rgba(110, 168, 255, 0.2);

  background:
    linear-gradient(rgba(160, 184, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(160, 184, 255, 0.045) 1px, transparent 1px),
    linear-gradient(180deg, #131b30, #0d1322);
  background-size: 24px 24px, 24px 24px, auto;

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 10px 24px rgba(4, 7, 16, 0.22);

  overflow: hidden;
}

/* Left accent rail -- Zomniverse signature (blue -> violet), not a
   language color. Identifies "Zomniverse real-code console", never
   "this language is this color". */
.zomniverse-code-block::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--zar-blue-strong, #6ea8ff), var(--zar-violet, #8b7cff));
  opacity: 0.9;
  pointer-events: none;
}

/* =========================================================
   HEADER / IDENTITY ROW

   [context (dot + label)]   [language]            [Copy]

   A real flex row in normal document flow, not floating absolute
   labels over the code -- avoids collisions at any width and lets
   the context group wrap onto its own line on very narrow screens
   while Copy stays anchored and reachable.
========================================================= */

.zomniverse-code-header {
  position: relative;
  z-index: 1;

  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;

  padding: 0.6rem 0.85rem 0.6rem 1.1rem;
  border-bottom: 1px solid rgba(160, 184, 255, 0.12);
  background: rgba(6, 10, 20, 0.28);
}

.zomniverse-code-context {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

/* Hidden by default -- the generic, non-ZAR variant (Learn, future
   modules). Revealed only under a real .zar-llm-insight--coding
   ancestor -- see the header comment above for why this is CSS-
   driven rather than decided by the enhancer itself. */
.zomniverse-code-context-dot {
  display: none;
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
}

.zar-llm-insight--coding .zomniverse-code-context-dot {
  display: inline-block;
  /* exact color, reused: llm_zar_ai_header.css's
     .zar-llm-insight--coding .zar-answer-mini-dot */
  background: #5eead4;
  /* exact glow, reused: llm_zar_ai_header.css's
     .zar-llm-insight--coding .zar-ai-icon-wrap box-shadow */
  box-shadow:
    0 0 8px rgba(94, 234, 172, 0.55),
    0 0 16px rgba(56, 189, 248, 0.28);
}

.zomniverse-code-context-label {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(224, 228, 245, 0.5);
  white-space: nowrap;
}

/* "ZAR " prefix, added only under the same Coding City ancestor --
   inherits text-transform:uppercase above, so this renders as
   "ZAR CODE", matching the approved mockup. Never adds "Verified"/
   "Validated"/a checkmark -- see the truth-contract note above. */
.zar-llm-insight--coding .zomniverse-code-context-label {
  color: var(--zar-text-on-dark-secondary, rgba(218, 216, 239, 0.74));
}

.zar-llm-insight--coding .zomniverse-code-context-label::before {
  content: "ZAR ";
}

.zomniverse-code-language {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--zar-text-on-dark, #f5f2ff);
  opacity: 0.92;
  white-space: nowrap;
}

/* =========================================================
   COPY BUTTON

   Exactly one per eligible block (owned entirely by
   learn-code-copy.js's enhanceCodeBlocks()/click handler -- this
   file only styles it). Copies code.textContent only, unaffected by
   Prism tokenization (see zar_code_syntax_highlighter.js).
========================================================= */

.zomniverse-code-copy {
  margin: 0 0 0 auto;
  flex: none;

  display: inline-flex;
  align-items: center;
  gap: 0.32em;

  padding: 0.3em 0.7em;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 0.5rem;

  background: rgba(255, 255, 255, 0.05);
  color: var(--zar-text-on-dark-strong, #ffffff);

  font-family: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.4;
  white-space: nowrap;

  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.zomniverse-code-copy-icon {
  width: 13px;
  height: 13px;
  flex: none;
}

.zomniverse-code-copy:hover {
  background: rgba(255, 255, 255, 0.11);
  border-color: rgba(255, 255, 255, 0.24);
}

.zomniverse-code-copy:active {
  transform: translateY(1px);
}

.zomniverse-code-copy:focus-visible {
  outline: 2px solid var(--zar-blue-strong, #6ea8ff);
  outline-offset: 2px;
}

.zomniverse-code-copy.is-copied {
  background: rgba(126, 231, 199, 0.14);
  border-color: rgba(126, 231, 199, 0.4);
  color: var(--zar-green-bright, #7ee7c7);
}

/* =========================================================
   CODE BODY
========================================================= */

.zomniverse-code-block pre {
  color: #48a9ed;
  position: relative;
  z-index: 1;
  display: block;
  margin: 0;
  padding: 1rem 1.15rem 1.15rem;

  overflow-x: auto;
  -webkit-overflow-scrolling: touch;

  background: transparent;
  white-space: pre;
}

/* =========================================================
   PATCH 2026-08-28g | BASE FOREGROUND SPECIFICITY FIX

   Root cause (forensic trace, "Investigate the live code-console
   presentation handoff" task): Styles/modes/zar/zar_answer_stream.css
   has a pre-dark-console rule --
   ".genebean_guard_answer--final .zar-llm-stream-content
   pre.zar-code-block code" (and 5 ancestor-context alternates) --
   that sets "color: inherit;" at specificity (0,3,2). This file's
   own ".zomniverse-code-block code" selector is only (0,1,1), so
   that legacy rule still won the cascade for the <code> element's
   base color, leaving untokenized identifiers (plain variable names
   Prism's grammars don't tag, e.g. numbers/total/n/values) inheriting
   a dark, light-theme-prose color onto the new dark console surface.

   Verified before reaching for !important: a selector that beats
   (0,3,2) without !important IS possible here (e.g. repeating this
   same class 4x: ".zomniverse-code-block.zomniverse-code-block
   .zomniverse-code-block.zomniverse-code-block code" -> (0,4,1)) --
   but that repeated-class specificity hack is fragile (silently
   falls behind again if the legacy rule ever gains one more ancestor
   class, and reads as a mistake to a future maintainer likely to
   "clean it up"), and the task explicitly forbids reproducing
   zar_answer_stream.css's ZAR-specific ancestor chain inside this
   shared, mode-agnostic file. A single, narrowly-scoped, documented
   !important on exactly this one property is the smaller and more
   robust fix: it expresses the actual invariant directly ("this
   dark console's base readability must never lose to an external
   ancestor-scoped rule, regardless of that rule's specificity now or
   later") rather than encoding a specificity number that can go
   stale. Scope is exactly one declaration, on this class only.

   This does NOT affect Prism's .token.* spans below -- an element
   with its own explicit (non-inherited) color always ignores a
   parent's color, !important or not; !important only changes which
   declaration an element uses for ITS OWN property when several
   compete. Token spans keep their own semantic colors unchanged.
========================================================= */

.zomniverse-code-block code {
  display: inline;
  background: none;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 0.9rem;
  line-height: 1.68;
  white-space: pre;
  text-shadow: none;
}

/* =========================================================
   RESPONSIVE

   On very narrow screens the Copy label hides (icon remains,
   aria-label still announces the full action) so Copy stays compact
   and reachable; context + language may wrap onto their own line
   above it, per the approved design.
========================================================= */

@media (max-width: 480px) {
  .zomniverse-code-header {
    padding: 0.55rem 0.7rem 0.55rem 0.9rem;
  }

  .zomniverse-code-block pre {
    padding: 0.85rem 0.85rem 0.95rem;
    font-size: 0.85rem;
  }

  .zomniverse-code-copy {
    padding: 0.28em 0.6em;
    font-size: 0.72rem;
  }

  .zomniverse-code-copy-label {
    display: none;
  }
}

@media print {
  .zomniverse-code-copy {
    display: none;
  }
}

/* =========================================================
   ONE SEMANTIC SYNTAX TOKEN PALETTE -- language-independent.

   Populated by Scripts/shared/ui/zar_code_syntax_highlighter.js
   calling Prism.highlightElement() post-finalization; this file
   only ever styles the resulting .token.* spans. Every hue below is
   an EXISTING --zar-* brand token; nothing invented. Same rules
   apply regardless of whether Prism tokenized Python, R, or
   JavaScript -- there is no Python palette / R palette / JavaScript
   palette, only this one, shared everywhere.

   If Prism support for a given language is unavailable (grammar not
   vendored), the code element is left as plain escaped text by
   zar_code_syntax_highlighter.js -- these rules then simply never
   match anything, and the block still renders correctly, just
   without token colors.
========================================================= */

.zomniverse-code-block .token.keyword,
.zomniverse-code-block .token.control,
.zomniverse-code-block .token.directive,
.zomniverse-code-block .token.import,
.zomniverse-code-block .token.keyword.control {
  color: var(--zar-violet, #8b7cff);
  font-weight: 600;
}
:root {
  --function: #1a66d9;
}
.zomniverse-code-block .token.function,
.zomniverse-code-block .token.method {
  color: var(--function, #5c7ec3);
}
:root {
  --string-char-template: #9e009b;
  --token-number: #3c30e6;
  --string-char-template: #9e009b;
}
.zomniverse-code-block .token.string,
.zomniverse-code-block .token.char,
.zomniverse-code-block .token.template-string {
  color: #fc5bf9;
}

.zomniverse-code-block .token.number {
  color: var(--token-number, #1a66d9);
}

.zomniverse-code-block .token.comment {
  color: #8892ad;
  font-style: italic;
}
:root { 
  --operator-color:  #e22396;
}
.zomniverse-code-block .token.operator,
.zomniverse-code-block .token.arrow {
  color: var(--operator-color, #5c5757);
}

.zomniverse-code-block .token.punctuation {
  color: rgba(224, 228, 245, 0.55);
}

.zomniverse-code-block .token.builtin,
.zomniverse-code-block .token.constant,
.zomniverse-code-block .token.boolean,
.zomniverse-code-block .token.known-class-name {
  color: var(--zar-danger, #ff9ca9);
}

.zomniverse-code-block .token.class-name {
  color: var(--zar-blue-strong, #6ea8ff);
  font-weight: 600;
}

/* variables/parameters: no distinct token color -- inherit the
   block's own foreground (var(--zar-text-on-dark) above). Prism's
   default python/r/javascript grammars do not tag plain
   identifiers, so this is the correct, honest behavior rather than
   a fabricated color. */
