Mercurial
view mrjunejune/src/jrpg/jrpg.css @ 260:1f9877b637e9
Add Copilot-powered cyberpunk JRPG chat
Integrate the production JRPG chat with Seobeo streaming, Deita persistence, and a Bazel-managed Copilot SDK and LiteLLM inference stack.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <mrjunejune@users.noreply.github.com> |
|---|---|
| date | Wed, 05 Aug 2026 09:19:41 -0700 |
| parents | 667156fcd3e3 |
| children | b401627fc49e |
line wrap: on
line source
@font-face { font-family: "Pixel Mplus"; src: url("/public/fonts/pixel-mplus-12-regular.ttf") format("truetype"); font-display: block; } :root { --mjj-jrpg-art: url("/public/jrpg/bar-ink.webp"); --mjj-jrpg-canvas: var(--zenbu-sys-color-surface-page); --mjj-jrpg-surface: var(--zenbu-sys-color-surface-default); --mjj-jrpg-surface-raised: var(--zenbu-sys-color-surface-raised); --mjj-jrpg-surface-sunken: var(--zenbu-sys-color-surface-sunken); --mjj-jrpg-text: var(--zenbu-sys-color-text-primary); --mjj-jrpg-text-muted: var(--zenbu-sys-color-text-secondary); --mjj-jrpg-frame: var(--zenbu-sys-color-border-strong); --mjj-jrpg-frame-soft: var(--zenbu-sys-color-border-subtle); --mjj-jrpg-primary: var(--zenbu-sys-color-action-primary-background); --mjj-jrpg-primary-hover: var(--zenbu-sys-color-action-primary-background-hover); --mjj-jrpg-primary-foreground: var(--zenbu-sys-color-action-primary-foreground); --mjj-jrpg-accent: var(--zenbu-sys-color-danger-foreground); --mjj-jrpg-highlight: var(--zenbu-sys-color-warning-foreground); --mjj-jrpg-info: var(--zenbu-sys-color-info-foreground); --mjj-jrpg-success: var(--zenbu-sys-color-success-foreground); --mjj-jrpg-focus: var(--zenbu-sys-color-focus-outer); --mjj-jrpg-panel: color-mix( in srgb, var(--mjj-jrpg-surface) 92%, transparent ); --mjj-jrpg-panel-strong: color-mix( in srgb, var(--mjj-jrpg-surface-sunken) 92%, transparent ); } .jrpg-page { --zenbu-sys-font-family-ui: "Pixel Mplus"; --zenbu-sys-font-family-content: "Pixel Mplus"; --zenbu-sys-font-family-code: "Pixel Mplus"; min-width: 20rem; min-height: 100dvh; overflow: hidden; overflow-anchor: none; background: var(--mjj-jrpg-canvas); color: var(--mjj-jrpg-text); font-family: "Pixel Mplus"; font-size: var(--zenbu-sys-font-size-md); line-height: var(--zenbu-sys-line-height-md); } .jrpg-page * { font-family: inherit; } .jrpg-main { box-sizing: border-box; width: 100%; max-width: none; height: 100dvh; min-height: 0; padding: 0; } .jrpg-shell { box-sizing: border-box; display: block; width: 100%; max-width: none; height: 100%; margin: 0; padding: var(--zenbu-sys-padding-sm); border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); background: var(--mjj-jrpg-canvas); box-shadow: inset 0 0 0 var(--zenbu-sys-stroke-width) var(--mjj-jrpg-frame-soft); } .jrpg-workspace { display: grid; grid-template: "scene utility" minmax(0, 1fr) "composer menu" minmax(9rem, auto) / minmax(0, 1.22fr) minmax(19rem, 0.95fr); gap: var(--zenbu-sys-space-group); height: 100%; min-height: 0; } .jrpg-scene, .jrpg-utility, mjj-jrpg-composer, mjj-jrpg-menu, .jrpg-preview-panel { box-sizing: border-box; border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); border-radius: 0; } .jrpg-scene { grid-area: scene; display: grid; grid-template-columns: minmax(8rem, 0.38fr) minmax(15rem, 0.92fr); align-items: end; gap: var(--zenbu-sys-space-group); min-height: 0; padding: var(--zenbu-sys-padding-lg); overflow: hidden; background-image: linear-gradient( to top, color-mix( in srgb, var(--mjj-jrpg-canvas) 56%, transparent ), transparent 55% ), var(--mjj-jrpg-art); background-position: center; background-size: cover; } mjj-jrpg-character { display: block; align-self: end; min-width: 0; filter: drop-shadow( var(--zenbu-sys-space-related) var(--zenbu-sys-space-related) 0 color-mix(in srgb, var(--mjj-jrpg-frame) 35%, transparent) ); } mjj-jrpg-character img { display: block; width: 100%; max-height: 25rem; object-fit: contain; object-position: center bottom; border-radius: 0; animation: mjj-jrpg-idle 2.4s steps(2, end) infinite; } mjj-jrpg-character[state="thinking"] img { animation-duration: 0.8s; } @keyframes mjj-jrpg-idle { 50% { transform: translateY(calc(var(--zenbu-sys-space-related) * -1)); } } mjj-jrpg-chat { position: relative; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; align-self: stretch; min-height: 0; padding: var(--zenbu-sys-padding-md); border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); background: var(--mjj-jrpg-panel-strong); box-shadow: inset 0 0 0 var(--zenbu-sys-stroke-width) var(--mjj-jrpg-info); } .jrpg-panel-heading { display: flex; align-items: baseline; justify-content: space-between; gap: var(--zenbu-sys-space-group); padding-bottom: var(--zenbu-sys-padding-sm); border-bottom: var(--zenbu-sys-stroke-width) solid var(--mjj-jrpg-frame-soft); } .jrpg-panel-heading span, .jrpg-preview-kicker, .jrpg-menu-label, .jrpg-brand > p, .jrpg-dialog-heading p, .jrpg-preview-stats dt { color: var(--mjj-jrpg-text-muted); font-size: var(--zenbu-sys-font-size-xs); letter-spacing: 0.08em; } .jrpg-panel-heading h1 { margin: 0; color: var(--mjj-jrpg-text); font-size: var(--zenbu-sys-font-size-lg); } zen-message-scroller, .jrpg-message-viewport { display: block; min-height: 0; height: 100%; } .jrpg-message-viewport { overflow-y: auto; overflow-anchor: none; overscroll-behavior: contain; scrollbar-color: var(--mjj-jrpg-frame) transparent; } .jrpg-messages { display: grid; gap: var(--zenbu-sys-space-group); margin: 0; padding: var(--zenbu-sys-padding-md) 0; list-style: none; } .jrpg-message { display: grid; grid-template-columns: minmax(4rem, auto) 1fr; gap: var(--zenbu-sys-space-control); padding-left: var(--zenbu-sys-padding-sm); border-left: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-accent); } .jrpg-message[data-speaker="June"] { border-left-color: var(--mjj-jrpg-info); } .jrpg-message strong { color: var(--mjj-jrpg-highlight); font-weight: var(--zenbu-sys-font-weight-bold); } .jrpg-message p { margin: 0; color: var(--mjj-jrpg-text); } .jrpg-next { display: flex; align-items: center; justify-content: end; gap: var(--zenbu-sys-space-icon-label); margin: 0; color: var(--mjj-jrpg-primary); font-size: var(--zenbu-sys-font-size-xs); } .jrpg-utility { grid-area: utility; display: grid; grid-template-rows: auto minmax(0, 1fr); gap: var(--zenbu-sys-space-group); padding: var(--zenbu-sys-padding-md); background: var(--mjj-jrpg-surface); } .jrpg-brand { display: flex; align-items: end; justify-content: space-between; gap: var(--zenbu-sys-space-control); padding: 0 var(--zenbu-sys-padding-sm) var(--zenbu-sys-padding-sm); border-bottom: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); } body.jrpg-page .jrpg-brand header { width: auto; max-width: none; margin: 0; padding: 0; text-align: left; } body.jrpg-page .jrpg-brand header h1 { margin: 0; color: var(--mjj-jrpg-primary); font-size: var(--zenbu-sys-font-size-2xl); letter-spacing: 0; text-shadow: var(--zenbu-sys-space-icon-label) var(--zenbu-sys-space-icon-label) 0 var(--mjj-jrpg-accent); } .jrpg-brand > p { margin: 0; color: var(--mjj-jrpg-highlight); text-align: right; } mjj-jrpg-preview { display: block; min-height: 0; } .jrpg-preview-panel { display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto auto; gap: var(--zenbu-sys-space-group); height: 100%; padding: var(--zenbu-sys-padding-lg); background: linear-gradient( 135deg, var(--mjj-jrpg-surface-raised), var(--mjj-jrpg-surface) ); box-shadow: inset 0 0 0 var(--zenbu-sys-stroke-width) var(--mjj-jrpg-accent); } .jrpg-preview-panel h2, .jrpg-preview-panel p { margin: 0; } .jrpg-preview-panel h2 { color: var(--mjj-jrpg-primary); } .jrpg-preview-panel > p:not(.jrpg-preview-kicker) { color: var(--mjj-jrpg-text); } .jrpg-preview-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--zenbu-sys-space-control); margin: 0; } .jrpg-preview-stats div { padding: var(--zenbu-sys-padding-sm); border: var(--zenbu-sys-stroke-width) solid var(--mjj-jrpg-frame-soft); background: var(--mjj-jrpg-panel); } .jrpg-preview-stats dd { color: var(--mjj-jrpg-success); margin: var(--zenbu-sys-space-icon-label) 0 0; } .jrpg-preview-dialog > zen-button > button, .jrpg-preview-dialog dialog zen-button > :where(button, a) { width: 100%; border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); border-radius: 0; background: var(--mjj-jrpg-primary); color: var(--mjj-jrpg-primary-foreground); cursor: pointer; } .jrpg-preview-dialog > zen-button > button:hover, .jrpg-preview-dialog dialog zen-button > :where(button, a):hover { border-color: var(--mjj-jrpg-primary-hover); background: var(--mjj-jrpg-primary-hover); } .jrpg-preview-dialog dialog { box-sizing: border-box; width: min(82vw, 46rem); max-width: calc(100% - var(--zenbu-sys-space-content)); padding: var(--zenbu-sys-padding-xl); border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); border-radius: 0; background: var(--mjj-jrpg-surface-raised); color: var(--mjj-jrpg-text); box-shadow: inset 0 0 0 var(--zenbu-sys-stroke-width) var(--mjj-jrpg-accent), var(--zenbu-sys-space-control) var(--zenbu-sys-space-control) 0 var(--mjj-jrpg-accent); } .jrpg-preview-dialog dialog::backdrop { background: color-mix(in srgb, var(--mjj-jrpg-canvas) 84%, transparent); } .jrpg-preview-dialog dialog[open] { animation: mjj-jrpg-dialog-open var(--zenbu-sys-motion-duration-layout) var(--zenbu-sys-motion-ease-enter); } @keyframes mjj-jrpg-dialog-open { from { clip-path: inset(48% 25%); transform: scaleX(0.35); } to { clip-path: inset(0); transform: scaleX(1); } } .jrpg-dialog-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--zenbu-sys-space-group); padding-bottom: var(--zenbu-sys-padding-md); border-bottom: var(--zenbu-sys-stroke-width) solid var(--mjj-jrpg-frame-soft); } .jrpg-dialog-heading p, .jrpg-preview-dialog dialog > p { margin: 0; } .jrpg-dialog-heading zen-button { width: auto; } .jrpg-dialog-heading zen-button > button { width: var(--zenbu-control-height); min-width: var(--zenbu-control-height); padding: 0; border-color: var(--mjj-jrpg-accent); background: var(--mjj-jrpg-surface); color: var(--mjj-jrpg-text); } .jrpg-preview-dialog dialog h2 { margin-top: var(--zenbu-sys-space-content); } .jrpg-preview-dialog dialog > p { margin-bottom: var(--zenbu-sys-space-content); } mjj-jrpg-composer { grid-area: composer; display: block; padding: var(--zenbu-sys-padding-md); background: var(--mjj-jrpg-surface); } .jrpg-composer { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--zenbu-sys-space-control); } .jrpg-composer zen-field { display: grid; gap: var(--zenbu-sys-space-icon-label); } .jrpg-composer label, .jrpg-composer-hint { grid-column: 1 / -1; color: var(--mjj-jrpg-text-muted); font-size: var(--zenbu-sys-font-size-xs); } .jrpg-composer textarea { box-sizing: border-box; width: 100%; min-height: calc(var(--zenbu-control-height) * 2); resize: vertical; padding: var(--zenbu-control-padding-block) var(--zenbu-control-padding-inline); border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); border-radius: 0; background: var(--mjj-jrpg-surface-sunken); color: var(--mjj-jrpg-text); font: inherit; } .jrpg-composer textarea::placeholder { color: var(--mjj-jrpg-text-muted); } .jrpg-page :where(a, button, textarea):focus-visible { outline: var(--zenbu-sys-focus-width) solid var(--mjj-jrpg-focus); outline-offset: var(--zenbu-sys-focus-offset); } .jrpg-composer zen-button { align-self: end; } .jrpg-composer zen-button > button { border: var(--zenbu-sys-stroke-width-emphasis) solid var(--mjj-jrpg-frame); border-radius: 0; background: var(--mjj-jrpg-primary); color: var(--mjj-jrpg-primary-foreground); cursor: pointer; } .jrpg-composer zen-button > button:hover { border-color: var(--mjj-jrpg-primary-hover); background: var(--mjj-jrpg-primary-hover); } .jrpg-composer [data-cancel-control] > button { border-color: var(--mjj-jrpg-accent); background: var(--mjj-jrpg-accent); } .jrpg-composer button:disabled { opacity: var(--zenbu-sys-opacity-disabled); cursor: not-allowed; } .jrpg-composer-hint { margin: 0; } mjj-jrpg-menu { grid-area: menu; display: block; padding: var(--zenbu-sys-padding-md); background: var(--mjj-jrpg-surface-sunken); } mjj-jrpg-menu nav { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: var(--zenbu-sys-space-group); height: 100%; } .jrpg-menu-label { margin: 0; writing-mode: vertical-rl; } mjj-jrpg-menu ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--zenbu-sys-space-control); margin: 0; padding: 0; list-style: none; } mjj-jrpg-menu zen-button, mjj-jrpg-menu button { width: 100%; } mjj-jrpg-menu button { justify-content: start; border: var(--zenbu-sys-stroke-width) solid transparent; border-radius: 0; background: transparent; color: var(--mjj-jrpg-text); cursor: pointer; } mjj-jrpg-menu button:hover { border-color: var(--mjj-jrpg-accent); color: var(--mjj-jrpg-primary-hover); } mjj-jrpg-menu button[aria-pressed="true"] { border-color: var(--mjj-jrpg-frame); background: var(--mjj-jrpg-surface-raised); color: var(--mjj-jrpg-primary); } mjj-jrpg-menu button zen-icon { opacity: 0; } mjj-jrpg-menu button[aria-pressed="true"] zen-icon { opacity: 1; } @media (max-width: 52rem) { .jrpg-page { overflow-y: auto; } .jrpg-main { height: auto; min-height: 100dvh; padding: 0; } .jrpg-shell { height: auto; min-height: 100dvh; } .jrpg-workspace { grid-template: "scene" auto "utility" auto "menu" auto "composer" auto / minmax(0, 1fr); height: auto; min-height: 0; } .jrpg-scene { min-height: 34rem; } .jrpg-utility { min-height: 27rem; } mjj-jrpg-menu nav { grid-template-columns: 1fr; } .jrpg-menu-label { writing-mode: initial; } mjj-jrpg-menu ul { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (max-width: 34rem) { .jrpg-main { padding: 0; } .jrpg-scene { grid-template-columns: 1fr; grid-template-rows: minmax(12rem, 0.6fr) minmax(20rem, 1fr); min-height: 42rem; padding: var(--zenbu-sys-padding-md); } mjj-jrpg-character { justify-self: center; width: min(15rem, 65%); } mjj-jrpg-character img { max-height: 15rem; } .jrpg-brand { align-items: center; } .jrpg-brand > p { max-width: 9rem; } .jrpg-composer { grid-template-columns: 1fr; } .jrpg-composer zen-button { width: 100%; } .jrpg-composer zen-button > button { width: 100%; } mjj-jrpg-menu ul { grid-template-columns: 1fr; } .jrpg-preview-dialog dialog { width: calc(100% - var(--zenbu-sys-space-group)); max-width: none; padding: var(--zenbu-sys-padding-lg); } } @media (prefers-reduced-motion: reduce) { mjj-jrpg-character img, .jrpg-preview-dialog dialog[open] { animation: none; } } @media (forced-colors: active) { .jrpg-scene { background-image: none; } }