/* MOONSHOT — atomic-age space-poster shell. Palette mirrors src/palette.js (frozen hexes) in oklch: ink #16121F ≈ oklch(0.194 0.026 298) night #1E1B3A ≈ oklch(0.243 0.058 286) cream #F4E9D2 ≈ oklch(0.937 0.033 85) red #E8452C ≈ oklch(0.623 0.204 32) gold #F2B33D ≈ oklch(0.806 0.147 79) teal #35C4B5 ≈ oklch(0.743 0.119 184) grass #3F7D4E ≈ oklch(0.535 0.098 150) dirt #C98A5B ≈ oklch(0.686 0.099 57) white #FFF8EC ≈ oklch(0.981 0.018 81) */ /* ---------- reset (good-css foundations) ---------- */ *, *::before, *::after { box-sizing: border-box; min-inline-size: 0; } :root { /* color tokens */ --ink: oklch(0.194 0.026 298); --night: oklch(0.243 0.058 286); --cream: oklch(0.937 0.033 85); --red: oklch(0.623 0.204 32); --gold: oklch(0.806 0.147 79); --teal: oklch(0.743 0.119 184); --grass: oklch(0.535 0.098 150); --dirt: oklch(0.686 0.099 57); --white: oklch(0.981 0.018 81); --ink-55: color-mix(in oklch, var(--ink) 55%, transparent); --ink-90: color-mix(in oklch, var(--ink) 90%, transparent); --ink-dim: color-mix(in oklch, var(--ink) 72%, var(--cream)); /* type + display-size tokens */ --font-display: 'Arial Black', 'Arial Narrow Bold', Impact, 'Haettenschweiler', sans-serif; --font-mono: 'Courier New', Courier, monospace; --display: clamp(2.4rem, 1.5rem + 4vw, 4.8rem); /* the one fluid display size */ --stamp-size: clamp(2.8rem, 1.4rem + 7.5vw, 7rem); --text-ui: clamp(0.9rem, 0.8rem + 0.4vw, 1.05rem); /* print-chrome geometry */ --border: 3px solid var(--ink); --shadow: 4px 4px 0 var(--ink); --radius: 4px; /* motion */ --ease-out: cubic-bezier(0.23, 1, 0.32, 1); --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); color-scheme: dark; font-synthesis: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; } body { margin: 0; block-size: 100dvb; overflow: clip; /* fullscreen game shell, no scroll */ background: var(--night); color: var(--cream); font-family: var(--font-display); /* controls carry their own user-select: none below */ } h1, h2, p { margin: 0; } ::selection { background: var(--gold); color: var(--ink); } /* hidden must always win over display rules below */ [hidden] { display: none !important; } /* ---------- canvas mount ---------- */ #game { position: fixed; inset: 0; cursor: crosshair; } #game canvas { display: block; inline-size: 100%; block-size: 100%; } /* ---------- print overlays: halftone grain + scanlines ---------- */ .grain, .scanlines, #flash { position: fixed; inset: 0; pointer-events: none; } /* halftone dots + paper mottle, pure layered gradients */ .grain { z-index: 2; opacity: 0.28; background-image: radial-gradient(circle, var(--ink-90) 0 0.5px, transparent 0.65px), radial-gradient(circle, color-mix(in oklch, var(--white) 35%, transparent) 0 0.6px, transparent 0.75px), radial-gradient(120% 90% at 50% 40%, transparent 55%, var(--ink-55) 100%); background-size: 6px 6px, 10px 10px, 100% 100%; background-position: 0 0, 3px 5px, 0 0; } .scanlines { z-index: 3; opacity: 0.5; background-image: repeating-linear-gradient( 0deg, var(--ink-90) 0 1px, transparent 1px 4px ); } /* hit flash: cream screen; main.js sets .style.opacity, so NO transition here */ #flash { z-index: 4; background: var(--cream); opacity: 0; } /* ---------- HUD: minor-league scoreboard corners ---------- */ #hud { position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 10; display: flex; justify-content: space-between; align-items: flex-start; padding-block-start: clamp(0.75rem, 0.5rem + 1vw, 1.25rem); padding-inline: clamp(0.75rem, 0.5rem + 1vw, 1.25rem); pointer-events: none; } .hud-block { background: var(--cream); color: var(--ink); border: var(--border); box-shadow: var(--shadow); padding-block: 0.5rem 0.65rem; padding-inline: 0.85rem 1rem; text-transform: uppercase; } .hud-level { rotate: -1deg; } /* push the right block below the fixed mute button (resolves top-right conflict) */ .hud-score { rotate: 1deg; margin-block-start: 3.4rem; text-align: end; } #level-num, #hr-count { font-family: var(--font-mono); font-weight: bold; font-size: var(--text-ui); letter-spacing: 0.06em; } #level-name { font-size: clamp(0.85rem, 0.7rem + 0.5vw, 1.1rem); color: var(--red); letter-spacing: 0.04em; } #total-hr { font-family: var(--font-mono); font-weight: bold; font-size: 0.8rem; letter-spacing: 0.1em; color: var(--ink-dim); } /* pitch dots: ink squares, red once used (main.js fills ) */ #pitch-dots { display: flex; justify-content: flex-end; gap: 5px; margin-block: 0.35rem; } #pitch-dots i { inline-size: 11px; block-size: 11px; background: var(--ink); border: 1px solid var(--ink); } #pitch-dots i.used { background: var(--red); } /* ---------- center result stamp ---------- */ #stamp, #stamp-sub { position: fixed; inset-inline: 0; z-index: 15; text-align: center; pointer-events: none; opacity: 0; -webkit-text-stroke: 2px var(--ink); paint-order: stroke fill; } #stamp { inset-block-start: 50%; translate: 0 -52%; font-size: var(--stamp-size); letter-spacing: 0.02em; rotate: -2deg; } #stamp-sub { inset-block-start: calc(50% + var(--stamp-size) * 0.62); font-family: var(--font-mono); font-weight: bold; font-size: clamp(1rem, 0.85rem + 1vw, 1.4rem); letter-spacing: 0.18em; -webkit-text-stroke-width: 0; color: var(--cream); } #stamp.show, #stamp-sub.show { opacity: 1; } /* kind colors — misprint = accent offset behind the ink outline */ #stamp.homerun { color: var(--gold); text-shadow: 5px 5px 0 var(--red), 7px 7px 0 var(--ink-90); } #stamp.inplay { color: var(--white); text-shadow: 4px 4px 0 var(--teal), 6px 6px 0 var(--ink-90); } #stamp.popup { color: var(--cream); text-shadow: 4px 4px 0 var(--dirt), 6px 6px 0 var(--ink-90); } #stamp.foul { color: var(--cream); text-shadow: 4px 4px 0 var(--red), 6px 6px 0 var(--ink-90); } #stamp.planet { color: var(--cream); text-shadow: 5px 5px 0 var(--gold), 8px 8px 0 var(--red), 10px 10px 0 var(--ink-90); } #stamp.sign { color: var(--gold); text-shadow: 4px 4px 0 var(--red), 6px 6px 0 var(--ink-90); } #stamp.wall { color: var(--teal); text-shadow: 4px 4px 0 var(--ink-90); } #stamp.crowd { color: var(--gold); text-shadow: 4px 4px 0 var(--teal), 6px 6px 0 var(--ink-90); } #stamp.whiff { color: var(--red); text-shadow: 4px 4px 0 var(--ink-90); } #stamp.strike { color: var(--gold); text-shadow: 4px 4px 0 var(--ink-90); } #stamp.ball { color: var(--teal); text-shadow: 4px 4px 0 var(--ink-90); } @keyframes stamp-in { 0% { scale: 1.6; rotate: 3deg; opacity: 0; } 60% { scale: 0.94; opacity: 1; } 80% { scale: 1.04; } 100% { scale: 1; rotate: 0deg; opacity: 1; } } /* ---------- home-run distance readout ---------- */ #distance { position: fixed; inset-block-end: clamp(3.2rem, 2rem + 5vw, 6rem); inset-inline: 0; z-index: 16; display: flex; align-items: baseline; justify-content: center; gap: 0.4rem; pointer-events: none; font-family: var(--font-display); font-size: clamp(2.2rem, 1.2rem + 5vw, 4.6rem); line-height: 1; color: var(--gold); text-shadow: 4px 4px 0 var(--red), 6px 6px 0 var(--ink-90); opacity: 0; translate: 0 12px; transition: opacity 0.3s var(--ease-out), translate 0.3s var(--ease-out); } #distance.show { opacity: 1; translate: 0 0; } #distance .ft-unit { font-size: 0.42em; letter-spacing: 0.12em; color: var(--cream); text-shadow: 3px 3px 0 var(--ink-90); } /* ---------- hint + mute button ---------- */ #hint { position: fixed; inset-block-end: clamp(0.8rem, 0.5rem + 1vw, 1.4rem); inset-inline: 0; z-index: 10; text-align: center; font-family: var(--font-mono); font-weight: bold; font-size: 0.85rem; letter-spacing: 0.22em; color: var(--teal); text-shadow: 2px 2px 0 var(--ink-90); pointer-events: none; } #btn-mute { position: fixed; inset-block-start: clamp(0.75rem, 0.5rem + 1vw, 1.25rem); inset-inline-end: clamp(0.75rem, 0.5rem + 1vw, 1.25rem); z-index: 40; padding-block: 0.45rem; padding-inline: 0.8rem; font-family: var(--font-mono); font-weight: bold; font-size: 0.8rem; letter-spacing: 0.08em; } /* ---------- overlay cards ---------- */ #overlay { position: fixed; inset: 0; z-index: 20; display: grid; place-items: safe center; overflow: clip; padding-inline: 1rem; pointer-events: none; } #overlay.dim { background: var(--ink-55); pointer-events: auto; } .card { pointer-events: auto; background: var(--cream); color: var(--ink); border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow); rotate: -1deg; inline-size: min(34rem, calc(100vi - 2.5rem)); padding-block: clamp(1.5rem, 1rem + 2vw, 2.5rem); padding-inline: clamp(1.25rem, 0.9rem + 1.5vw, 2rem); text-align: center; text-transform: uppercase; } /* title card logo: red/gold misprint offsets */ .logo { font-size: var(--display); line-height: 0.95; letter-spacing: 0.02em; color: var(--ink); text-shadow: 3px 3px 0 var(--red), 6px 6px 0 var(--gold); } .tagline { margin-block-start: 0.4rem; font-family: var(--font-mono); font-weight: bold; font-size: 0.8rem; letter-spacing: 0.3em; color: var(--red); } .howto { margin-block: 1.1rem 1.4rem; font-family: var(--font-mono); font-size: 0.8rem; line-height: 1.6; letter-spacing: 0.08em; } .foot { margin-block-start: 1.4rem; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.25em; color: var(--ink-dim); } .card-title { font-size: clamp(1.6rem, 1.2rem + 1.8vw, 2.4rem); line-height: 1; letter-spacing: 0.03em; color: var(--ink); text-shadow: 2px 2px 0 var(--gold); } .goal { margin-block-start: 0.6rem; font-family: var(--font-mono); font-weight: bold; font-size: 1rem; letter-spacing: 0.14em; color: var(--red); } .blurb { margin-block: 1rem 1.5rem; font-family: var(--font-mono); font-size: 0.85rem; line-height: 1.55; letter-spacing: 0.04em; text-transform: none; color: var(--ink-dim); } .stats { margin-block: 0.9rem 1.5rem; font-family: var(--font-mono); font-weight: bold; font-size: 0.95rem; line-height: 1.7; letter-spacing: 0.08em; white-space: pre-line; } /* modifier chips (main.js fills #intro-mods) */ .chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.45rem; margin-block-start: 0.8rem; } .chips:empty { display: none; } .chips > * { background: var(--gold); color: var(--ink); border: 2px solid var(--ink); box-shadow: 2px 2px 0 var(--ink); padding-block: 0.2rem; padding-inline: 0.6rem; font-family: var(--font-mono); font-weight: bold; font-size: 0.7rem; letter-spacing: 0.12em; } /* ---------- buttons ---------- */ button { font-family: var(--font-display); font-size: clamp(1rem, 0.9rem + 0.5vw, 1.25rem); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); background: var(--cream); border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding-block: 0.75rem; padding-inline: 1.6rem; cursor: pointer; touch-action: manipulation; user-select: none; -webkit-user-select: none; } button:active { translate: 2px 2px; box-shadow: 2px 2px 0 var(--ink); } .btn-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.9rem; } /* focus: ink ring on cream cards, teal ring on night for the mute button */ button:focus-visible { outline: max(3px, 0.12em) solid var(--ink); outline-offset: 3px; } #btn-mute:focus-visible { outline-color: var(--teal); } @media (hover: hover) and (pointer: fine) { button:hover { translate: 0 -2px; box-shadow: 4px 6px 0 var(--ink); } button:hover:active { translate: 2px 2px; box-shadow: 2px 2px 0 var(--ink); } } /* ---------- motion: opt-in, named properties ---------- */ @media (prefers-reduced-motion: no-preference) { button { transition: translate 120ms var(--ease-out), box-shadow 120ms var(--ease-out), background-color 120ms var(--ease-out); } #overlay { transition: background-color 180ms var(--ease-out); } #stamp.show, #stamp-sub.show { animation: stamp-in 0.42s var(--ease-out) both; } } /* ---------- noscript ---------- */ noscript { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; background: var(--night); } noscript p { background: var(--cream); color: var(--ink); border: var(--border); box-shadow: var(--shadow); rotate: -1deg; padding-block: 1rem; padding-inline: 1.5rem; font-family: var(--font-mono); font-weight: bold; }