/* nd10-theme.css — ND10 rebrand skin.
 *
 * ADDITIVE ONLY. This file changes two CUSTOM PROPERTY values and adds NEW
 * rules on top of EXISTING selectors (.tb-btn, .ds-ctab, .fs-enter-btn,
 * .ide-proj-add, .app-mode). It defines zero new HTML, removes zero
 * selectors, and deletes zero buttons — every control that exists today
 * keeps its exact markup and behavior; only its paint changes.
 *
 * Loaded via a single <link> after index.html's inline <style>, so cascade
 * order alone gives these rules priority without needing !important.
 *
 * Design source: nd10-shell-v8.html / nd10-open-v9.html mockups (approved
 * mockup round, 2026-08-06) — wireframe-corner-brackets × liquid-glass ×
 * dithered ambient corners. No sound in this pass (explicitly excluded).
 */

:root {
  /* ── Token remap ──────────────────────────────────────────────
     --blue is documented in index.html as "DevStudio accent — electric
     blue" — the mode this rebrand targets. --gold ("Folio accent") is a
     DELIBERATELY separate sub-brand and is left untouched on purpose: the
     ask was to skin DevStudio, not blur the two modes the app already
     distinguishes. */
  --blue:   #7cf5ff;
  --blue-d: rgba(124,245,255,.14);
  --blue-g: rgba(124,245,255,.30);

  /* New tokens this layer introduces, namespaced so they can never collide
     with the app's existing --bg/--rule/--text scale. */
  --nd-wire:      rgba(150,205,235,.20);
  --nd-wire-hot:  rgba(150,225,255,.55);
  --nd-glass-top: rgba(255,255,255,.10);
  --nd-glass-bot: rgba(0,0,0,.30);
  --nd-dither:    .40;   /* ambient corner opacity — one dial */
}

/* ── Corner brackets — a CONTAINER device, applied only to control-scale
   elements that are large enough to carry them (>=26px). Buttons under
   that height keep their existing look untouched; brackets on a control
   that small read as broken corners, which is the exact mistake an
   earlier mockup pass made and corrected. ── */
.nd-brk { position: relative; }
.nd-brk::before, .nd-brk::after {
  content: ''; position: absolute; width: 7px; height: 7px; pointer-events: none;
  background:
    linear-gradient(var(--nd-wire-hot), var(--nd-wire-hot)) top left / 7px 1px no-repeat,
    linear-gradient(var(--nd-wire-hot), var(--nd-wire-hot)) top left / 1px 7px no-repeat;
}
.nd-brk::before { top: -1px; left: -1px; }
.nd-brk::after  { bottom: -1px; right: -1px; transform: rotate(180deg); }

/* ── Topbar cluster buttons (.tb-btn) — glass background, brackets on the
   active state only, so idle chrome stays quiet. ── */
.tb-btn {
  background: linear-gradient(180deg, rgba(255,255,255,.03) 0%, rgba(255,255,255,.005) 60%, rgba(0,0,0,.08) 100%);
}
.tb-btn:hover {
  box-shadow: inset 0 1px 0 var(--nd-glass-top), inset 0 -1px 0 var(--nd-glass-bot);
}
.tb-btn.active,
.tb-btn.gold-active {
  position: relative;
  box-shadow: inset 0 1px 0 var(--nd-glass-top), inset 0 -1px 0 var(--nd-glass-bot),
              0 0 0 1px var(--nd-wire-hot);
}

/* ── Channels/Flows/Tools tab strip (.ds-ctab, from devstudio-chat-tabs.js)
   — same glass treatment, brackets on the active tab. ── */
.ds-ctab.active {
  position: relative;
  box-shadow: inset 0 1px 0 var(--nd-glass-top), 0 0 0 1px var(--nd-wire-hot);
}

/* ── Welcome-screen ENTER + mode buttons — the largest controls in the app,
   so these get the full bracket treatment. ── */
.fs-enter-btn,
.app-mode {
  position: relative;
}
.fs-enter-btn::before, .fs-enter-btn::after,
.app-mode::before, .app-mode::after {
  content: ''; position: absolute; width: 8px; height: 8px; pointer-events: none;
  background:
    linear-gradient(var(--nd-wire-hot), var(--nd-wire-hot)) top left / 8px 1px no-repeat,
    linear-gradient(var(--nd-wire-hot), var(--nd-wire-hot)) top left / 1px 8px no-repeat;
}
.fs-enter-btn::before, .app-mode::before { top: -1px; left: -1px; }
.fs-enter-btn::after,  .app-mode::after  { bottom: -1px; right: -1px; transform: rotate(180deg); }

/* ── Project-chip add button (.ide-proj-add) — small; glass only, no
   brackets, per the >=26px rule above. ── */
.ide-proj-add {
  background: linear-gradient(180deg, rgba(59,130,246,.10), rgba(59,130,246,.05));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
}

/* ── Ambient dither mount points ──────────────────────────────
   Canvases are inserted by nd10-ambient.js; this just positions and masks
   them so they never sit above interactive content (pointer-events:none)
   and never appear anywhere the script didn't explicitly place one. */
.nd-amb {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: var(--nd-dither);
}
.nd-amb canvas {
  display: block; width: 100%; height: 100%;
  image-rendering: pixelated; image-rendering: crisp-edges;
}
#welcome, #topbar { position: relative; }

/* ── One-time boot resolve ────────────────────────────────────
   The FINAL STAGE wordmark's glitch (.fs-wordmark::before/::after,
   .fs-ghost-r/.fs-ghost-c, .fs-box — all defined earlier in this file,
   3s infinite loops) was designed as an ambient idle effect and never
   stops. nd10-ambient.js adds `.nd-intro-done` to #welcome once, after
   the FIRST glitch burst completes (3.6s — matches the existing
   animation-delay:.6s + one 3s cycle exactly, so it freezes right as a
   burst finishes instead of cutting it off mid-glitch). This class does
   not touch the base keyframes at all — it only freezes them and fades
   the channel-split layers out, landing on the plain white wordmark the
   app already had. No brand/mark swap here — that's a separate,
   still-undecided decision. */
.nd-intro-done .fs-wordmark::before,
.nd-intro-done .fs-wordmark::after,
.nd-intro-done .fs-ghost-r,
.nd-intro-done .fs-ghost-c {
  animation: none !important;
  opacity: 0;
  transition: opacity .5s ease-out;
}
.nd-intro-done .fs-box { animation: none !important; }

/* the resolve sweep — a single accent-colored line, added as a real DOM
   node by nd10-ambient.js (never CSS-generated content on an existing
   element), so it can never collide with the wordmark's own pseudo-elements */
.nd-resolve-sweep {
  position: absolute; left: 0; right: 0; top: 50%; height: 2px;
  background: var(--blue, #7cf5ff);
  box-shadow: 0 0 14px var(--blue, #7cf5ff);
  opacity: 0; pointer-events: none; z-index: 2;
}
.nd-resolve-sweep.run {
  animation: nd-sweep .5s ease-out both;
}
@keyframes nd-sweep {
  0%   { opacity: 1; transform: translateY(-46px); }
  100% { opacity: 0; transform: translateY(46px); }
}
@media (prefers-reduced-motion: reduce) {
  .nd-resolve-sweep { display: none; }
}
