Mercurial
diff mrjunejune/src/jrpg/jrpg.css @ 259:667156fcd3e3
Add dev-only cyberpunk JRPG page
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Wed, 05 Aug 2026 09:19:41 -0700 |
| parents | |
| children | 1f9877b637e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrjunejune/src/jrpg/jrpg.css Wed Aug 05 09:19:41 2026 -0700 @@ -0,0 +1,685 @@ +@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 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; + } +}