Skip to content

[v0.5]: Brand Architecture + KOT Pass + Context Screen - #6

Merged
Kyonax merged 15 commits into
masterfrom
context-screen
Sep 1, 2026
Merged

[v0.5]: Brand Architecture + KOT Pass + Context Screen#6
Kyonax merged 15 commits into
masterfrom
context-screen

Conversation

@Kyonax

@Kyonax Kyonax commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Checklist (check if it applies)

  • Contains testing instructions
  • Requires environment / credential changes
  • Requires special deployment steps
  • Has unit / integration tests
  • Touches licensing, security, or CI
  • License headers on new files (LICENSING.org)
  • Attribution preserved on modified files
  • Lint passes (npm run lint)
  • Security rules followed (SECURITY.org)
  • No credentials committed
  • All GitHub Checks have passed (no Pre-Check Failed label applied by CI)
  • CHANGELOG.org updated (release PRs only)
  • Version bumped (release PRs only)

What does this PR do?

Brings the whole post-v0.3 line onto master as one branch: the brand-driven architecture that lets a folder define a brand, the @kyonax_on_tech visual pass, and the CONTEXT screen — a second web source that puts video context on screen from an .org file, driven live from an OBS dock while recording. Consolidates the work that previously sat in a three-deep PR stack (dev, feat-brand_kot, context-screen); the superseded pull requests are closed and their commits ride along here.

As a content creator running OBS, I want the video's title, description and tags on a dedicated CONTEXT scene that I can toggle without leaving the capture, so that a recording ships with context already burned in and nothing waits on an edit pass.

Design / Reference: Scope and conventions in CONTRIBUTING.org and CHANGELOG.org.

Implementation

[NEW] new file · [MOD] modified file · [DEL] removed · [MOV] renamed or relocated

Brand tree (@kyonax_on_tech/)

  • [NEW] brand.js — brand identity and metadata read by the loader
  • [NEW] sources/hud/cam-log.vue — CAM-LOG overlay, bracket label fed by the control plane
  • [NEW] sources/hud/context-screen.vue — news-style lower third plus sidebar HUD for the CONTEXT scene
  • [NEW] styles/_theme.scss — per-brand theme tokens, self-contained inside the brand folder
  • [MOV] sources.js — source registry, moved out of src/shared/data/overlays.js so a brand owns its own manifest

Discovery (src/shared/)

  • [NEW] brand-loader.js — globs @*/ for brands, sources and context .org files and exposes BRANDS / SOURCES / CONTEXTS
  • [NEW] brand-loader.test.js — schema and discovery contract for every registered brand and source

UI primitives (src/shared/components/ui/)

  • [NEW] badge.vue — status pill
  • [NEW] chip.vue — tag chip used by the context tag row
  • [NEW] data-point.vue — label plus value readout
  • [NEW] icon.vue — single inline SVG entry point
  • [NEW] org-content.vue — renders a parsed org AST as HUD markup
  • [NEW] org-content.test.js — AST-to-markup coverage
  • [NEW] status-dot.vue — layered breathing status dot

HUD components (src/shared/components/hud/)

  • [MOV] frame.vue — from src/shared/components/hud-frame.vue
  • [MOV] timer.vue — from src/shared/components/recording-timer.vue
  • [DEL] src/shared/components/corner-bracket.vue — replaced by an inline SVG asset
  • [DEL] src/shared/components/preview-modal.vue — superseded by the modal split under src/views/components/modals/
  • [DEL] src/shared/components/status-indicator.vue — superseded by ui/status-dot.vue

Composables (src/shared/composables/)

  • [NEW] use-context-channel.js — BroadcastChannel relay carrying the context selection, sidebar state, live draft and cam label, persisted across reloads
  • [NEW] composables.test.js — singleton and lifecycle coverage for the shared composables
  • [MOD] use-audio-analyzer.js — event-driven analyzer, singleton per source
  • [MOD] use-obs-websocket.js — single shared socket instead of one per component
  • [MOD] use-recording-status.js — direct DOM writes on the hot path
  • [MOD] use-scene-name.js — shared scene subscription

Utilities (src/shared/utils/)

  • [NEW] highlight.js — Shiki code highlighting for the context code reveal
  • [NEW] org.js.org parse to the locked context schema
  • [NEW] org.test.js — parser coverage including malformed input

Widgets (src/shared/widgets/)

  • [NEW] hud/audio-meter.vue — audio meter split into the HUD kind folder
  • [MOV] ui/live-readout.vue — from src/shared/widgets/live-readout.vue
  • [DEL] src/shared/widgets/audio-meter.vue — replaced by the kind-folder version

Landing and control surface (src/views/)

  • [NEW] control.vue — narrow single-column panel for mounting as an OBS Custom Browser Dock
  • [NEW] components/modals/base.vue — shared modal shell
  • [NEW] components/modals/context-control.vue — picks the active context and toggles each block
  • [NEW] components/modals/detail.vue — per-source detail
  • [NEW] components/modals/preview.vue — sub-pixel accurate iframe preview
  • [NEW] components/sections/footer.vue — landing footer
  • [NEW] components/sections/hero.vue — landing hero
  • [NEW] components/sections/setup.vue — OBS setup instructions
  • [NEW] components/sections/sources.vue — source grid driven by the loader
  • [NEW] components/sections/stats.vue — source counters
  • [NEW] utils/markup.js — landing-only markup helpers
  • [MOV] components/elements/card.vue — from src/shared/components/overlay-card.vue
  • [MOD] home.vue — composed from the extracted sections

App shell and assets (src/)

  • [NEW] app/fonts/Geomanist/GeomanistBold.ttf — brand font, bold cut
  • [NEW] app/fonts/Geomanist/GeomanistItalic.ttf — brand font, italic cut
  • [NEW] app/fonts/Geomanist/GeomanistRegular.ttf — brand font, regular cut
  • [NEW] shared/assets/svg/corner-bracket.svg — bracket as an asset instead of a component
  • [DEL] brands/kyonax-on-tech/cam-person.vue — replaced by the brand-folder source
  • [DEL] shared/data/overlays.test.js — folded into brand-loader.test.js
  • [MOD] App.vue — router shell only
  • [MOD] main.js — brand loader bootstrap
  • [MOD] router.js — per-brand source routes plus the /control dock route
  • [MOD] shared/version.js — version surface consumed by the landing
  • [MOD] shared/version.test.js — matching coverage
  • [MOD] app/scss/abstracts/_mixins.scsscyberpunk-glow removed, halo lifted to opt-in tokens
  • [MOD] app/scss/abstracts/_theme.scss — 60-30-10 colour rebalance
  • [MOD] app/scss/abstracts/_variables.scss — motion and surface tokens
  • [MOD] app/scss/base/_global.scsscontain: layout paint on HUD sub-trees
  • [MOD] app/scss/base/_typography.scss — Geomanist face registration
  • [MOD] app/scss/components/_index.scss — component layer index
  • [MOD] app/scss/layout/_index.scss — layout layer index

OBS integration (tools/obs/, exported/)

  • [NEW] tools/obs/reckit-context.py — OBS script panel driving the context screen with file selection, live .org drafting and hotkeys
  • [NEW] tools/obs/install-dock.sh — registers the control panel in global.ini, backs it up and refuses to run while OBS is open
  • [NEW] exported/context.json — exported CONTEXT scene collection
  • [NEW] exported/main.json — exported MAIN scene collection

CI & Tooling

  • [NEW] .shipwright/contract.toml — unattended-run contract gating src/** behind a pull request and every commit behind lint and tests
  • [NEW] tsconfig.eslint.json — type-aware lint project
  • [MOD] .github/workflows/ci.yml — coverage for the new source tree
  • [MOD] .github/workflows/release.yml — release gate wiring
  • [MOD] eslint.config.mjs — Vue plugin, naming convention and import sorting
  • [MOD] vite.config.js — alias registry for the kind-folder layout
  • [MOD] .env.example — documented variables for the new sources
  • [MOD] .gitattributes — binary font handling
  • [MOD] .gitignore — untracked personal context content, plus Python bytecode from the OBS tools

Dependencies

  • Runtime added: dayjs, shiki, uniorg-parse
  • Dev added: @typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint-plugin-vue, vue-eslint-parser
  • Upgraded:
  • Removed:
  • Lockfile: regenerated for the added packages

Docs

  • [NEW] CONTRIBUTING.org — contribution rules and the naming conventions this branch follows
  • [MOD] CHANGELOG.org — TODO block pruned against what shipped
  • [MOD] README.org — brand-folder architecture and the CONTEXT source
  • [MOD] LICENSING.org — coverage for the added asset kinds
  • [MOD] NOTICE — third-party attribution for the added runtime packages
  • [MOD] index.html — app shell metadata
  • [MOD] .github/PULL_REQUEST_TEMPLATE.md — the 13 embedded format rules
  • [MOD] .github/SECURITY.org — disclosure policy refresh

Technical Details

  • Brands discovered from the filesystem

    • Chose: a build-time glob over @*/ that yields BRANDS, SOURCES and CONTEXTS
    • Over: a hand-maintained registry module listing every source
    • Why: adding a brand or an overlay becomes dropping a folder, and the registry can never drift from what is on disk
    • Trade-off: a malformed brand folder fails at build time rather than where it was edited
  • Control plane over BroadcastChannel

    • Chose: a same-origin BroadcastChannel relay with localStorage persistence, carrying selection, sidebar state, live draft and cam label
    • Over: routing every toggle through the OBS WebSocket
    • Why: the dock and the HUD are two browser sources in one origin, so the state never needs to leave the browser and survives a source reload
    • Trade-off: control is confined to one machine and one origin — nothing crosses to a second box
  • Context authored as .org, parsed at glob time

    • Chose: .org files parsed with uniorg-parse into a locked schema at discovery
    • Over: JSON or YAML context files
    • Why: the context is prose the author already writes in org, and parsing once at glob time keeps the render path free of parser work
    • Trade-off: a parser lands in the runtime bundle, and malformed files surface as a parse_error entry rather than a build failure
  • Context content stays out of the repository

    • Chose: ignore @kyonax_on_tech/data/contexts/ and assert only the discovery plumbing in tests
    • Over: committing sample context files so the assertions can be strict
    • Why: context files are per-video personal notes; the rendering plumbing is the shared part and is what a clean checkout has to prove
    • Trade-off: CI cannot assert real parse output for a brand, only that the maps resolve
  • Glow lifted out of the mixin layer

    • Chose: delete the cyberpunk-glow mixin and expose halo and glow as opt-in :root tokens, with contain: layout paint on HUD sub-trees
    • Over: keeping the mixin and applying it selectively
    • Why: the mixin was applied broadly enough to dominate the frame budget in OBS; opting in makes the cost visible at the call site
    • Trade-off: existing overlays had to be revisited one by one to restore the intended look

Testing Coverage

Test runner: Vitest 4 with happy-dom
Command: npm test

Automated tests

Test file Covers Tests Status
src/shared/brand-loader.test.js Brand, source and context discovery contract 39
src/shared/utils/org.test.js Org parse to the locked context schema 15
src/shared/components/ui/org-content.test.js AST rendered to HUD markup 11
src/shared/composables/composables.test.js Singleton and lifecycle behaviour 11
src/shared/version.test.js Version surface 3

Total: 79 tests across 5 files, all passing.

Quality gates (run on every PR)

Gate Source Status
ESLint eslint.config.mjs via npm run lint ✅ 0 errors
Unit Tests npm test in .github/workflows/ci.yml ✅ 79/79
Security Scan .github/workflows/ci.yml
License Headers .github/workflows/ci.yml
Protected Files .github/workflows/ci.yml
Pre-Check Failed label pre-check-label job in .github/workflows/ci.yml ✅ label absent

How to test this PR

feat(context): news-style lower-third + sidebar HUD
├─ Setup
├─ Landing and source discovery
├─ Context screen in OBS
└─ Control dock

Setup

Prereqs: Node 20 or newer, OBS with a MAIN and a CONTEXT scene.

  1. Install and start the dev server — npm ci && npm run dev
    Expected: Vite serves on http://localhost:5173 with no console errors.
  2. Create your own context content directory — mkdir -p @kyonax_on_tech/data/contexts, then add a <slug>.org with a title, description and tags.
    Expected: the directory stays untracked; git status reports a clean tree.

Landing and source discovery

Prereqs: dev server running.

  1. Open http://localhost:5173
    Expected: the sources grid lists every registered source with its status, and the counters in the stats section match that count.
  2. Open the preview modal for cam-log
    Expected: the iframe renders the overlay at 1920x1080 scaled without sub-pixel blur.

Context screen in OBS

Prereqs: a CONTEXT scene in OBS.

  1. Add a Browser Source pointing at http://localhost:5173/@kyonax_on_tech/context-screen, sized 1920x1080 with a transparent background.
    Expected: the lower-third strip renders with no camera feed behind it and no opaque backdrop.
  2. Toggle the sidebar and each content block from the control surface.
    Expected: blocks appear and disappear in the OBS source without a refresh.

Control dock

Prereqs: OBS fully closed before step 1.

  1. Register the dock — bash tools/obs/install-dock.sh
    Expected: the script backs up global.ini, reports success, and refuses to run if OBS is open.
  2. Start OBS, load tools/obs/reckit-context.py under Tools then Scripts, pick a context file and type into the live draft field.
    Expected: the CONTEXT browser source follows every keystroke, and the cam-log bracket label follows the label field.

Special Deployment Requirements

  1. OBS must be closed before installing the dock (CRITICAL)tools/obs/install-dock.sh edits global.ini; OBS overwrites that file on exit and would discard the registration.
  2. Context content is not in the repository (REQUIRED) — create @kyonax_on_tech/data/contexts/ locally; a clean checkout renders the placeholder until a .org file exists there.
  3. Scene collections are exported, not imported automatically (OPTIONAL) — import exported/main.json and exported/context.json from OBS to start from the reference scene layout.

Documentation

SCREENSHOT — CONTEXT scene lower third

The news-style strip and sidebar as they render over a live camera feed.

Pending — attach a capture from the CONTEXT scene.

SCREENSHOT — Control dock in OBS

The control panel mounted as a Custom Browser Dock beside the scene list.

Pending — attach a capture of the docked panel.

Kyonax and others added 7 commits April 17, 2026 00:54
…le headers

Refinement pass on the v0.3 overlay card system and project
documentation. Four areas of work.

1. Overlay card fixes. Removed overflow: hidden that was
   clipping corner-bracket SVGs. Replaced the px-based
   auto-fill grid with mobile-first 1fr columns (1 col
   default, 2 at sm/48em, 3 at lg/82.667em). Added
   truncation for consistent card height: 3-line CSS clamp
   on descriptions, max 3 use_case tags and requires items
   with +N overflow indicators. Always-visible DETAILS
   button opens a full-content detail modal.

2. Modal abstraction. Extracted base-modal.vue (reusable
   shell with backdrop, ESC, teleport, fade, named slots).
   Refactored preview-modal.vue to use it. Created
   detail-modal.vue as a second consumer for overlay info.
   Extracted parseEmphasis into shared utils.

3. cam-person renamed to cam-log across 7 files (Vue
   component, router, overlays.js id + path, CHANGELOG,
   ci.yml comment, local buffers) for consistency with the
   display name CAM-LOG.

4. Tier 1 file headers. Established a standardized header
   pattern for all root config/setup/org files using figlet
   smslant ASCII art with cyberpunk place names. Applied to
   11 files: .gitignore (the void), vite.config.js (the
   forge), eslint.config.mjs (the precinct), index.html
   (the gate), .gitattributes (the lab), .env.example (the
   vault), ci.yml (the watchtower), release.yml (the
   checkpoint), CHANGELOG.org (the logs), README.org (the
   bridge), LICENSING.org (the pact). Each header follows:
   license, figlet art, filename + date, description, TOC,
   optional guidelines/requirements, author/contact.

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
…xes, Tier 1 headers

Comprehensive refinement and architectural refactor of the
v0.3 codebase. Six areas of work.

1. Brand-driven architecture. Each @brand/ folder at the
   project root is now the single source of truth for that
   brand. brand-loader.js auto-discovers brands + sources
   via import.meta.glob. Routes generate dynamically from
   discovered sources. Centralized overlays.js deleted,
   replaced by per-brand sources.js. src/brands/ removed.
   cam-log.vue moved to @kyonax_on_tech/hud/cam-log.vue.
   Brand metadata (identity, colors, links) in brand.js.
   Theme injection in App.vue via route meta.

2. Vite aliases + import cleanup. Added @shared, @views,
   @app, @assets aliases. Converted all imports from
   relative paths to alias-based. Zero ../  paths remain.
   Landing page components (overlay-card, modals,
   parse-emphasis) separated from src/shared/ to
   src/views/ since they are landing-page-only.

3. ESLint Vue SFC + naming conventions. Added
   eslint-plugin-vue with flat/essential processor for
   script setup support. Added @typescript-eslint/
   naming-convention for CCS standards enforcement on
   plain JS (snake_case vars, camelCase functions,
   UPPER_CASE constants, PascalCase classes). Created
   tsconfig.eslint.json for type-aware linting.

4. Overlay card fixes. Removed overflow: hidden, mobile-
   first 1fr grid, description 3-line clamp, max 3
   use_case tags and requires with +N indicators,
   always-visible DETAILS button with detail-modal.

5. Tier 1 file headers. Figlet smslant ASCII art with
   cyberpunk place names on 15 root config/setup/org
   files. Structured layout: license, art, filename,
   date, description, TOC, guidelines, author/contact.

6. Documentation + security. CONTRIBUTING.org created
   with setup, conventions, workflow, CI, PR process.
   SECURITY.org expanded with banned patterns table,
   enforcement layers, contributor checklist. .gitignore
   hardened with additional secret-file patterns. README
   updated with Setup section and Contributing summary.

31 files changed, 1611 insertions, 336 deletions.
26 tests passing, 0 lint errors, clean build.

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
Splits the component layer by kind (views into sections /
elements / modals; shared components into ui / hud), extracts
five real sections out of home.vue, adds one Vite alias per
kind-folder, and rewrites all template tags to PascalCase so
they match the import binding. 18 files touched.

1. views/components/ split by kind

   Three new subfolders with a single purpose each:

     sections/   top-level page regions (one per page)
     elements/   reusable list items (v-for children)
     modals/     overlay surfaces (shell + instances)

   Existing view files moved into their kind folder:

     overlay-card.vue    to  elements/card.vue
     base-modal.vue      to  modals/base.vue
     preview-modal.vue   to  modals/preview.vue
     detail-modal.vue    to  modals/detail.vue

2. Five sections extracted from home.vue

     meta.vue     sticky stats strip — SOURCES/BRANDS/READY/CANVAS
     hero.vue     ASCII logo + tagline + SYS.LOG/version tags
     setup.vue    QUICK SETUP six-step flow
     sources.vue  brand tabs + filter bar + grid
     footer.vue   author + license line

   home.vue slimmed from ~655 lines to ~80. Filter state —
   search_query, status_filter, selected_brand — moved out of
   home.vue and into sources.vue where it is actually consumed.

3. shared/components/ renamed to Option-C short filenames

     components/hud-frame.vue         to  components/hud/frame.vue
     components/recording-timer.vue   to  components/hud/timer.vue
     components/status-indicator.vue  to  components/ui/status.vue

   Filenames drop the kind; the kind comes back at the
   import-binding layer as <HudFrame>, <HudTimer>, <UiStatus>.

4. Corner-bracket Vue component to raw SVG asset

   components/corner-bracket.vue deleted. Replaced by a raw SVG
   at assets/svg/corner-bracket.svg plus a new generic loader at
   components/ui/icon.vue using import.meta.glob with the ?raw
   query. New icons are now "drop the file into the folder" — no
   more one-SFC-per-icon boilerplate.

5. Seven new Vite kind-aliases in vite.config.js

     @Sections     src/views/components/sections/
     @elements     src/views/components/elements/
     @modals       src/views/components/modals/
     @ui           src/shared/components/ui/
     @hud          src/shared/components/hud/
     @widgets      src/shared/widgets/
     @composables  src/shared/composables/

   Alias count grows from 4 to 11. Every kind-folder has one.

6. Template tags and imports rewritten

   All tags in touched files switched to PascalCase to match the
   import binding. cam-log.vue, frame.vue, timer.vue, card.vue,
   preview.vue, detail.vue, sources.vue, home.vue. Bindings
   follow the kind suffix/prefix registry:

     @Sections   XxxSection   HeroSection, MetaSection, ...
     @modals     XxxModal     BaseModal, PreviewModal, ...
     @elements   Xxx          Card
     @ui         UiXxx        UiIcon, UiStatus
     @hud        HudXxx       HudFrame, HudTimer
     @widgets    as-is        AudioMeter, LiveReadout

Validation: 26/26 tests pass, 0 lint errors (7 pre-existing
warnings), production build clean in 1.15s.

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
Post-Part-A refinement pass. Seven coherent changes that tighten
naming discipline, deduplicate view SCSS, isolate web sources from
shared HUD vocabulary, and fix the silently-broken brand theming
chain. 23 files staged.

1. Three new shared/components/ui/ primitives

     data-point.vue   <UiDataPoint>   label/value tile (sm | lg)
     chip.vue         <UiChip>        lowercase pill (solid | overflow)
     badge.vue        <UiBadge>       uppercase status pill (active | dim)

   Replaced ~12 inline duplicates across stats.vue, card.vue, and
   detail.vue. ~40 lines of duplicated SCSS removed from consumers.
   All props-in-DOM-out — correctly placed in ui/ (no side-effects).

2. shared/widgets/ split by kind

     widgets/audio-meter.vue   to  widgets/hud/audio-meter.vue
     widgets/live-readout.vue  to  widgets/ui/live-readout.vue

   Mirrors the shared/components/hud|ui split: audio-meter is
   OBS-coupled (HUD-domain), live-readout is domain-agnostic.
   Consumers import via @widgets/hud/* and @widgets/ui/*.

3. Filenames describe purpose, never repeat the alias kind (Rule G)

     sections/meta.vue              to  sections/stats.vue
     ui/metric.vue                  to  ui/data-point.vue
     ui/status.vue                  to  ui/status-dot.vue
     views/utils/parse-emphasis.js  to  views/utils/markup.js

   "meta" was ambiguous (metadata/HTML-meta/meta-programming).
   "metric of what?" / "status shown how?" tests failed — multi-
   word names answer the question. Modals stay single-word
   (base/preview/detail.vue) because @modals/ already supplies
   "modal" — base-modal.vue would be redundant. Bindings keep
   the kind: <BaseModal>, <UiDataPoint>, <StatsSection>.

4. Utils as topic-based libraries (Rule J)

   markup.js holds parseEmphasis as a named export. Future markup
   parsers (parseLinks, parseCodeSpans) live in the same file.
   Never one-function-per-file. Composables exempt — one useX
   per file because hooks own state and lifecycle.

5. Brand folder restructured to mirror src/shared/

     @brand/hud/cam-log.vue   to  @brand/sources/hud/cam-log.vue
     @brand/animation/        to  @brand/sources/animation/
     @brand/scene/            to  @brand/sources/scene/

   Eliminates the clash where @brand/hud/ (web sources) and @hud/
   (shared HUD primitives) both used "hud". brand-loader.js globs
   updated; resolveComponent() key pattern now
   /<brand>/sources/<type>/<id>.vue. Reserved slots documented
   for brand-private components/{hud,ui}/, composables/,
   widgets/{hud,ui}/ (created only when 2+ files exist, Rule F).

6. <UiIcon> multi-pool SVG discovery

   Previously globbed only @shared/assets/svg/*.svg. Now also
   globs /@*/assets/svg/*.svg — any brand can drop SVGs in its
   own assets/svg/ folder and reference them by filename. Brand
   SVGs override shared SVGs on filename collision (useful for
   brand-flavored overrides of shared primitives).

7. Brand theming — SCSS single source of truth

   Fixed three silently-broken things:
     - @<brand>/styles/_theme.scss was orphaned (never imported).
     - brand.js colors duplicated the SCSS values.
     - brand.js held only a subset of palette ranges.

   Fix: src/main.js eagerly globs /@*/styles/_theme.scss so Vite
   bundles every brand theme into global CSS. brand.js lost its
   colors field entirely. App.vue dropped brand_theme_vars and
   only applies .brand-<handle> on route change — the CSS
   cascade does the rest. brand-loader test flipped from "has
   colors object" to "does NOT carry colors field" (enforcement).
   Verified: grep brand-kyonax-on-tech dist/assets/*.css
   matches in the production bundle.

Validation: 27/27 tests pass, 0 lint errors (7 pre-existing
warnings in use-audio-analyzer.js), production build clean in
1.25s.

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
feat: brand-driven architecture, ESLint Vue + naming, overlay card fixes, Tier 1 headers
Refine @kyonax_on_tech components and land a targeted perf pass
to restore OBS Browser Source fps on low-core hardware.

- cam-log: .hud-group layout; brand.js gains host + region;
  session-date now `${region} ∇ DD.MM.YYYY // ddd`
- remove cyberpunk-glow mixin (root cause of FPS drop); halo/glow
  reborn as opt-in :root tokens (--hud-halo, --hud-halo-text,
  --hud-glow)
- useRecordingStatus / useSceneName / useAudioAnalyzer →
  module-level singletons (one WS handler per event per page)
- audio analyzer: preallocated Float32Array + 256-entry
  JITTER_TABLE, event-driven off InputVolumeMeters, no rAF
- AudioMeter: direct DOM writes via template refs, quantized
  SCALE_STRINGS, write-threshold skip, ~10Hz emit,
  transform:scaleY() over animated height
- contain: layout paint on every frequently-updating HUD sub-tree
- UiStatusDot: static halo shell + animated-opacity .glow layer
  (dark shadow stays cached)
- preview modal: 100ms resize debounce; consume_trigger →
  consume-trigger (kebab-case)
- neutral-200 → neutral-100 across secondary text
- +composables.test.js: 6 singleton-contract tests (27 → 33)

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
Build context-screen as the second @kyonax_on_tech web source —
news-style lower-third with marquee row and toggleable right
sidebar that renders any .org-authored context with full
landing-page control via BroadcastChannel.

- pull Geomanist from kyo-web-online + declare --font-display,
  --surface-bg gradient, and 4 motion tokens on :root
- add uniorg-parse runtime dep (~25 KB gzipped, localhost-only)
- shared/utils/org.js: AST parser + metadata / marquee / body
  partitioner (Rule J topic library, OrgSchemaError)
- @ui/org-content.vue: recursive Vue template AST renderer; zero
  v-html (D11 — ESLint no-restricted-syntax bans innerHTML);
  D10 per-node styling for headlines / lists / checklists /
  tables / src+results / quotes / links / hr
- brand-loader.js: +CONTEXTS glob /@*/data/contexts/*.org +
  getContexts() helper
- @composables/use-context-channel.js: singleton BroadcastChannel
  composable + debounced localStorage persist + html-class toggle
- @kyonax_on_tech/sources/hud/context-screen.vue: full HUD source
  — strip (Geomanist + SpaceMono), marquee (translateX loop),
  sidebar (translateX slide + translateY auto-scroll on inner
  wrapper + custom lateral indicator), peek arrow (layered static
  halo + animated opacity); contain: layout paint on every sub-tree
- @ui/chip.vue: +shape prop (pill | square) for D15 sharp-corner lock
- @modals/context-control.vue: clickable slug list + sidebar toggle
  + live iframe preview; extends BaseModal
- @elements/card.vue: conditional CONTROLS button + modal mount
- 2 fixture .org files at @kyonax_on_tech/data/contexts/

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
@Kyonax Kyonax self-assigned this Apr 27, 2026
@Kyonax Kyonax added the Require Code Review The PR requires Code Review label Apr 27, 2026
@github-actions

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

Refine context-screen toward GitHub-flavored alert callouts, a
disciplined 60-30-10 palette where gold is reserved for the 10%
accent tier, per-page rem-base scaling for OBS readability, and
typography parity between sidebar headlines and alert titles.
Privatize the contexts/ folder so personal notes stay local.

- alerts: NOTE / TIP / IMPORTANT / WARNING / CAUTION via
  =[!TYPE]= quote-block prefix detection — Octicon SVG icons
  (info / light-bulb / report / alert / stop, MIT-licensed
  primer/octicons paths bound via =:d=, never v-html), per-type
  saturated 100-shade left-bar border + 6% color-mix surface +
  italic font-display body
- alert plumbing: WeakMap-cached =detectAlertType=, AST prefix-
  strip via shallow clone (no AST mutation), font-display
  forced on every descendant via =.org-alert :where(*)= +
  explicit =.org-content= override (the recursive UiOrgContent
  wrapper would otherwise cascade =font-mono= down)
- tertiary palette: +purple family (50–500, hue 266) added to
  =$colors= in =_variables.scss=; =--clr-tertiary-*= tokens
  emit automatically through =_theme.scss='s existing =@each=
- color rebalance (60-30-10): gold demoted out of headlines /
  tables / chips into the 10% accent tier (marquee, status
  dot, headline 3-dot stack, OUTPUT frame, alert borders);
  body neutrals shifted neutral-50 → neutral-100 globally for
  a less-light feel
- headline accent: replace the 3px gold =|= bar with three
  stacked 3px gold squares (single 3px square + ±6px box-
  shadow clones); =padding-left: 0.5em= + =transform:
  translateY(60%)= so the stack centers on the first text line
- code blocks: lang flag bg → primary-400, OUTPUT flag border
  + text → neutral-300 to mirror the src-block frame, ws
  markers 2px → 3px (darker neutral-400 / primary-400),
  =padding-top: 2.5em= so code clears the absolute label;
  src-block + example get =padding-bottom: 0.4em=
- tables: switch to inline =v-for= row/cell render — drop the
  recursive =UiOrgContent= inside =<tbody>= / =<tr>= because
  Chromium can mistreat =display: contents= on table-internal
  divs and collapse columns; =table-layout: fixed= +
  =word-break: break-word= on cells for narrow-sidebar fit
- sidebar/strip chrome: scope the html font-size base to the
  page via =html:has(.context-screen-overlay) { font-size:
  16px }= so every rem-based =--fs-*= renders ~33% larger in
  OBS without touching the global 12px base; sidebar ratio
  0.30 → 0.34; chip override → quiet outline (=fs-225=,
  neutral-100 text, transparent surface, =--clr-border-100=
  edge); strip =border-bottom= restored, marquee =border-top=
  dropped to avoid a 2px stack at the divider
- marquee: =v-if= on empty items so the gold strip doesn't
  render when a context has no =#+begin_marquee= block;
  separator squares 3px → 6px
- verbatim / inline-code: dark-neutral-400 pill + neutral-100
  text + =line-height: 1.5em= + =width: fit-content= safeguard
- quote: alert-format without header — =border-left: 1px
  solid var(--clr-border-100)=, italic, no gold left bar
- lists: chevron + checkbox markers via flex =align-self:
  center= + =transform: translateY(0.05em)= (the parent
  =align-items: baseline= ignores =vertical-align= on flex
  children); chevron rule generalized to non-ordered lists so
  descriptive lists also get markers; tighter marker right-
  margins
- title parity: =.org-headline= and =.org-alert__header= share
  =font-display= / weight 700 / =letter-spacing 0.06em= /
  uppercase — sidebar section titles and alert callout titles
  read as the same typography system
- privatize contexts: =@kyonax_on_tech/data/contexts/= added
  to =.gitignore= — personal notes stay local; only the
  rendering plumbing is tracked. Existing fixtures removed
  from the index via =git rm --cached=

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
@github-actions

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

- Main
- Context

Modified-by: Cristian D. Moreno (Kyonax) <kyonax25@gmail.com>
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

Changes:

- [NEW] .shipwright/contract.toml: Add contract gating src/ behind pull requests and commits behind lint/tests

Gates: lint 0, tests 79/79

Shipwright-Run: 2026-08-15T11-01-35-0500.385d29
@github-actions

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

Changes:

- [NEW] src/views/control.vue: Add a narrow single-column control surface listing contexts and toggling the sidebar for OBS docks
- [NEW] tools/obs/__pycache__/reckit-context.cpython-314.pyc: Compiled bytecode cache for the OBS script
- [NEW] tools/obs/install-dock.sh: Register the control panel in OBS global.ini, backing it up and refusing to run while OBS is open
- [NEW] tools/obs/reckit-context.py: Drive the context screen from an OBS script panel with file selection, live .org drafting and hotkeys
- [MOD] @kyonax_on_tech/sources/hud/cam-log.vue: Raise HUD text opacity so the cam log stays legible over bright footage
- [MOD] @kyonax_on_tech/sources/hud/context-screen.vue: Parse an incoming live draft at runtime ahead of the file context, falling back to the placeholder when malformed
- [MOD] src/router.js: Register the /control route so OBS can mount the panel as a Custom Browser Dock
- [MOD] src/shared/composables/use-context-channel.js: Carry a draft_org field through the channel snapshot, persistence and setters so live text overrides the file context

Gates: lint 0, tests 79/79

Shipwright-Run: 2026-08-31T18-02-01-0500.64e871
@github-actions

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

Changes:

- [MOD] @kyonax_on_tech/sources/hud/cam-log.vue: Render the top-right bracket from the relay label, falling back to SESSION when it is empty
- [MOD] @kyonax_on_tech/sources/hud/context-screen.vue: Pin the sidebar to the camera column and fix strip line-heights plus the strip/marquee shared border
- [MOD] src/shared/composables/use-context-channel.js: Carry cam_label through the relay state: persist, receive, broadcast, and expose setCamLabel
- [MOD] tools/obs/__pycache__/reckit-context.cpython-314.pyc: Rebuild the cached bytecode for the updated context script
- [MOD] tools/obs/reckit-context.py: Add a cam-log label field to the script properties and push it with every relay update

Gates: lint 0, tests 79/79

Shipwright-Run: 2026-08-31T21-01-23-0500.829a42
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

1 similar comment
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

Build / Config

  • vite.config.js was modified
  • .gitignore was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

@Kyonax
Kyonax changed the base branch from feat-brand_kot to master September 1, 2026 05:02
@Kyonax Kyonax changed the title feat(context): news-style lower-third + sidebar HUD [v0.5]: Brand Architecture + KOT Pass + Context Screen Sep 1, 2026
Changes:

- [MOD] src/shared/brand-loader.test.js: Assert the shape of the CONTEXTS and getContexts per-brand map rather than a non-empty map, so a clean checkout without the untracked context .org files passes
- [MOD] .gitignore: Ignore Python bytecode caches emitted by the OBS tools scripts
- [DEL] tools/obs/__pycache__/reckit-context.cpython-314.pyc: Drop the committed bytecode cache now that it is ignored

Gates: lint 0, tests 79/79
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Protected Files Modified

One or more files in the protected set were changed in this PR. Each category below explains why the file matters.

Legal / Licensing

  • NOTICE was modified
  • LICENSING.org was modified

Modifying these files changes the project's legal posture. Confirm with the maintainer before merging.

Governance

  • .github/SECURITY.org was modified
  • .github/PULL_REQUEST_TEMPLATE.md was modified

CODEOWNERS / SECURITY / PR template changes affect how every future PR is reviewed. Review carefully.

Supply Chain

  • package.json was modified
  • package-lock.json was modified

Dependency or lockfile changes. Verify the diff (no unexpected packages, no version downgrades).

CI / Security Config

  • .github/workflows/ci.yml was modified
  • .github/workflows/release.yml was modified
  • eslint.config.mjs was modified

Workflow / lint config. A quiet edit here can disable gates — diff against origin carefully.

Build / Config

  • vite.config.js was modified
  • .gitignore was modified
  • .env.example was modified

Build or gitignore config. Verify the build still passes and no ignored paths were accidentally un-ignored.

Release Artifact

  • CHANGELOG.org was modified
  • README.org was modified

Release-tracking files. Expected on release PRs; flag on non-release PRs.

@Kyonax
Kyonax merged commit d5b493c into master Sep 1, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Require Code Review The PR requires Code Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant