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;
+  }
+}