Initial addition of the Arcade study feature. Add connections as the first working game.
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m4s

This commit is contained in:
Elijah 2026-07-13 17:35:18 -07:00
parent 7b90409f2e
commit 611a585757
43 changed files with 5990 additions and 68 deletions

View file

@ -170,6 +170,334 @@
.animate-slide-up { animation: slideUp .32s var(--ease-spring); }
.animate-subtle-pulse { animation: subtlePulse 1.7s ease-in-out infinite; }
/* Arcade routes take over the complete application shell, including navigation. */
body:has(.arcade-route) {
--theme-bg-base: #070b18;
--theme-bg-surface: #11182a;
--theme-bg-surface-alt: #19233a;
--theme-bg-callout: #282357;
--theme-primary: #9a8cff;
--theme-primary-hover: #b5aaff;
--theme-text-heading: #f9f7ff;
--theme-text-body: #dbe2f4;
--theme-text-secondary: #aab6d1;
--theme-text-muted: #71809e;
--theme-border: #34415c;
--theme-border-light: #242f46;
min-height: 100vh;
background:
radial-gradient(circle at 76% 4%, rgba(116, 91, 255, .2), transparent 28rem),
radial-gradient(circle at 30% 92%, rgba(5, 198, 181, .11), transparent 34rem),
linear-gradient(145deg, #080c19, #0c1221 58%, #0b1020);
}
body:has(.arcade-route)::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
opacity: .11;
background-image: radial-gradient(rgba(201, 211, 255, .7) .7px, transparent .7px);
background-size: 22px 22px;
}
body:has(.arcade-route) main { min-height: 100vh; }
body:has(.arcade-route) .app-page { max-width: none; min-height: 100vh; }
body:has(.arcade-route) .arcade-route { width: min(100%, 1360px); margin-inline: auto; }
body:has(.arcade-route) .app-sidebar,
body:has(.arcade-route) .app-mobile-header {
border-color: rgba(138, 157, 201, .15);
background: rgba(8, 13, 27, .9);
box-shadow: 18px 0 55px rgba(0, 0, 0, .16);
}
body:has(.connections-world) {
background:
radial-gradient(circle at 28% 0%, rgba(88, 101, 242, .34), transparent 36rem),
radial-gradient(circle at 96% 28%, rgba(239, 71, 111, .16), transparent 30rem),
linear-gradient(145deg, #0b1329, #0e1932 54%, #142440);
}
.arcade-lobby-heading { position: relative; }
.arcade-lobby-heading::after {
content: "SELECT GAME";
position: absolute;
right: 0;
top: .5rem;
color: rgba(154, 140, 255, .08);
font-size: clamp(3rem, 8vw, 7rem);
font-weight: 950;
letter-spacing: -.06em;
line-height: .8;
pointer-events: none;
}
.arcade-cabinet {
position: relative;
display: flex;
min-height: 30rem;
flex-direction: column;
overflow: hidden;
border: 1px solid rgba(148, 163, 202, .2);
border-radius: 1.75rem;
background: #11182a;
box-shadow: inset 0 1px rgba(255,255,255,.06), 0 22px 55px rgba(0,0,0,.28);
transition: transform .24s var(--ease-spring), box-shadow .24s ease, border-color .24s ease;
}
.arcade-cabinet.is-playable:hover { transform: translateY(-7px) rotate(-.3deg); border-color: rgba(181,170,255,.65); box-shadow: 0 30px 70px rgba(0,0,0,.38), 0 0 45px rgba(126,103,255,.13); }
.arcade-cabinet.is-coming { filter: saturate(.82); }
.arcade-visual { position: relative; height: 13.5rem; overflow: hidden; border-bottom: 1px solid rgba(255,255,255,.1); }
.arcade-cabinet-copy { display: flex; flex: 1; flex-direction: column; padding: 1.25rem; }
.arcade-cabinet-status { font-size: .65rem; font-weight: 900; letter-spacing: .18em; text-transform: uppercase; }
.arcade-cabinet-copy h3 { margin-top: .35rem; color: white; font-size: 1.55rem; font-weight: 900; letter-spacing: -.04em; }
.arcade-cabinet-copy > p:not(.arcade-cabinet-status) { margin-top: .55rem; flex: 1; color: #aab6d1; font-size: .86rem; line-height: 1.65; }
.arcade-cabinet-action { display: grid; min-height: 2.9rem; margin-top: 1.1rem; place-items: center; border: 1px solid rgba(255,255,255,.13); border-radius: .9rem; color: #8d9ab5; background: rgba(5,9,20,.3); font-size: .8rem; font-weight: 850; }
.is-playable .arcade-cabinet-action { color: #14152a; border-color: transparent; background: linear-gradient(135deg, #a89dff, #8170f5); box-shadow: 0 10px 28px rgba(126,103,255,.28); }
.connections-visual { display: grid; place-items: center; background: radial-gradient(circle at 50% 20%, rgba(180,162,255,.35), transparent 55%), linear-gradient(145deg,#342c64,#1d2042); }
.connections-visual-grid { display: grid; width: 9.5rem; grid-template-columns: repeat(4, 1fr); gap: .38rem; transform: perspective(400px) rotateX(8deg) rotateZ(-2deg); }
.connections-visual-grid i { aspect-ratio: 1; border-radius: .5rem; box-shadow: inset 0 1px rgba(255,255,255,.45), 0 5px 10px rgba(0,0,0,.22); }
.connections-visual-grid i:nth-child(-n+4) { background: #ffd166; }
.connections-visual-grid i:nth-child(n+5):nth-child(-n+8) { background: #5ee0a0; }
.connections-visual-grid i:nth-child(n+9):nth-child(-n+12) { background: #5ac8fa; }
.connections-visual-grid i:nth-child(n+13) { background: #b69cff; }
.connections-visual-label { position: absolute; right: 1rem; bottom: .75rem; color: rgba(255,255,255,.6); font-size: .62rem; font-weight: 900; letter-spacing: .16em; text-transform: uppercase; }
.crossword-visual { display: grid; place-items: center; background: linear-gradient(150deg,#f4dca1,#c98c45); }
.crossword-visual::before { content: ""; position: absolute; inset: 0; opacity: .12; background-image: linear-gradient(#412911 1px,transparent 1px),linear-gradient(90deg,#412911 1px,transparent 1px); background-size: 18px 18px; }
.crossword-grid { display: grid; width: 10rem; grid-template-columns: repeat(8,1fr); gap: 2px; transform: rotate(-3deg); filter: drop-shadow(0 12px 12px rgba(71,38,10,.28)); }
.crossword-grid i { display: grid; aspect-ratio: 1; place-items: center; background: #312419; color: transparent; font-size: .62rem; font-style: normal; font-weight: 950; }
.crossword-grid i.has-letter { color: #322112; background: #fff9e9; }
.crossword-pencil { position: absolute; right: 1.2rem; bottom: .55rem; color: #6d3e17; font-size: 3rem; transform: rotate(-24deg); text-shadow: 0 5px 8px rgba(64,35,10,.2); }
.arcade-cabinet-crossword .arcade-cabinet-status { color: #f3bb62; }
.blocks-visual { background: linear-gradient(#071a20,#0a3436); }
.blocks-visual::before { content: ""; position: absolute; inset: 0; opacity: .18; background-image: linear-gradient(rgba(74,222,128,.45) 1px,transparent 1px),linear-gradient(90deg,rgba(74,222,128,.45) 1px,transparent 1px); background-size: 24px 24px; }
.blocks-piece { position: absolute; display: grid; gap: 3px; }
.blocks-piece i,.blocks-floor i { border: 1px solid rgba(255,255,255,.35); border-radius: 4px; box-shadow: inset 0 0 8px rgba(255,255,255,.25),0 0 13px currentColor; }
.blocks-piece-a { left: 32%; top: 18%; grid-template-columns: repeat(2,1.8rem); color: #38e6c5; animation: arcadeBlockHover 2s ease-in-out infinite; }
.blocks-piece-a i { width: 1.8rem; height: 1.8rem; background: #0fcbaa; }
.blocks-piece-b { right: 18%; top: 42%; grid-template-columns: repeat(3,1.55rem); color: #ff4f91; transform: rotate(90deg); }
.blocks-piece-b i { width: 1.55rem; height: 1.55rem; background: #ed397e; }
.blocks-floor { position: absolute; right: 12%; bottom: 1rem; left: 12%; display: grid; grid-template-columns: repeat(6,1fr); gap: 3px; }
.blocks-floor i { aspect-ratio: 1; color: #ffc857; background: #eaaa2e; }
.blocks-floor i:nth-child(3n) { color: #6c7cff; background: #5868ee; transform: translateY(-1.5rem); }
.blocks-arrow { position: absolute; left: 19%; top: 20%; color: rgba(103,232,211,.5); font-size: 2.2rem; animation: arcadeArrowDown 1.3s ease-in-out infinite; }
.arcade-cabinet-falling-blocks .arcade-cabinet-status { color: #49ddb6; }
.asteroid-visual { background: radial-gradient(circle at 72% 28%,#253c74,#101735 45%,#070b19); }
.arcade-star { position: absolute; width: 3px; height: 3px; border-radius: 50%; background: white; box-shadow: 0 0 8px white; }
.star-a { left: 16%; top: 18%; }.star-b { right: 18%; top: 12%; }.star-c { left: 48%; top: 39%; }
.asteroid { position: absolute; border: 2px solid #8c91a6; border-radius: 47% 53% 42% 58%; background: radial-gradient(circle at 32% 28%,#9299ac,#4c5268 62%,#292e41); box-shadow: inset -7px -8px 12px rgba(0,0,0,.35),0 8px 18px rgba(0,0,0,.35); }
.asteroid::after { content: ""; position: absolute; width: 28%; height: 24%; left: 18%; top: 22%; border-radius: 50%; background: rgba(32,37,55,.45); }
.asteroid-a { width: 3.2rem; height: 3rem; right: 14%; top: 18%; transform: rotate(18deg); }.asteroid-b { width: 2rem; height: 2rem; left: 16%; top: 27%; }.asteroid-c { width: 1.4rem; height: 1.35rem; right: 32%; bottom: 18%; }
.space-station { position: absolute; left: 20%; bottom: 18%; width: 4rem; height: 1.4rem; border-radius: 65% 20% 35% 65%; background: linear-gradient(90deg,#b9c8ef,#6f83bd); transform: rotate(-12deg); box-shadow: 0 0 20px rgba(105,151,255,.35); }
.space-station::before { content: ""; position: absolute; left: 1.2rem; bottom: 1rem; border-right: 1rem solid transparent; border-bottom: 1.5rem solid #53699f; border-left: .25rem solid transparent; }
.space-station i { position: absolute; right: -.75rem; top: .3rem; width: 1rem; height: .8rem; border-radius: 50%; background: #50e6ff; box-shadow: 0 0 16px #4fdff8; }
.laser-beam { position: absolute; width: 38%; height: 2px; left: 42%; top: 52%; background: linear-gradient(90deg,#70f4ff,transparent); transform: rotate(-20deg); transform-origin: left; box-shadow: 0 0 8px #52e7ff; }
.shield-ring { position: absolute; left: 8%; bottom: 4%; width: 7.5rem; height: 6rem; border: 2px solid rgba(90,221,255,.25); border-radius: 50%; transform: rotate(-15deg); }
.arcade-cabinet-asteroid-defense .arcade-cabinet-status { color: #65c9ff; }
@keyframes arcadeBlockHover { 0%,100% { transform: translateY(0); } 50% { transform: translateY(8px); } }
@keyframes arcadeArrowDown { 0%,100% { opacity: .3; transform: translateY(-5px); } 50% { opacity: .8; transform: translateY(6px); } }
/* Connections has its own playful game-show visual system, independent of the desk UI. */
.connections-world {
--theme-bg-surface: #182443;
--theme-bg-surface-alt: #223154;
--theme-bg-callout: #2c3d68;
--theme-primary: #ffd166;
--theme-primary-hover: #ffe29a;
--theme-text-heading: #f8fbff;
--theme-text-body: #dbe7ff;
--theme-text-secondary: #afc0df;
--theme-text-muted: #8497bd;
--theme-border: #52668d;
--theme-border-light: #33486f;
position: relative;
isolation: isolate;
overflow: hidden;
color: var(--theme-text-body);
background:
radial-gradient(circle at 10% 0%, rgba(88, 101, 242, .45), transparent 28rem),
radial-gradient(circle at 95% 25%, rgba(239, 71, 111, .2), transparent 25rem),
linear-gradient(145deg, #101a35 0%, #111d39 48%, #172846 100%);
box-shadow: 0 28px 80px rgba(8, 15, 34, .28);
}
.connections-hub.connections-world,
.connections-stage.connections-world {
overflow: visible;
background: transparent;
box-shadow: none;
}
.connections-hub.connections-world::before,
.connections-stage.connections-world::before { display: none; }
.connections-world::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
opacity: .13;
background-image:
linear-gradient(rgba(255,255,255,.18) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,.18) 1px, transparent 1px);
background-size: 42px 42px;
mask-image: linear-gradient(to bottom, black, transparent 78%);
}
.connections-world .editorial-title {
font-family: var(--font-manrope), ui-sans-serif, system-ui, sans-serif;
font-weight: 850;
letter-spacing: -.045em;
}
.connections-hub-hero,
.connections-topbar,
.connections-status,
.connections-setup,
.connections-import {
backdrop-filter: blur(18px);
box-shadow: inset 0 1px rgba(255,255,255,.08), 0 18px 45px rgba(2, 8, 23, .22);
}
.connections-hub-hero {
background: linear-gradient(120deg, rgba(34,49,84,.94), rgba(24,36,67,.72));
border: 1px solid rgba(151, 174, 221, .18);
}
.connections-pack-card {
border-color: rgba(117, 141, 187, .28);
background: rgba(24, 36, 67, .74);
box-shadow: inset 0 1px rgba(255,255,255,.05), 0 12px 30px rgba(3, 9, 24, .16);
}
.connections-pack-card:hover {
transform: translateY(-2px);
border-color: rgba(255, 209, 102, .48);
}
.connections-pack-card.is-active {
border-color: #ffd166;
background: linear-gradient(120deg, rgba(65, 72, 132, .9), rgba(38, 55, 96, .9));
box-shadow: 0 0 0 1px rgba(255,209,102,.25), 0 18px 45px rgba(3,9,24,.25);
}
.connections-primary-button {
color: #172033;
background: linear-gradient(135deg, #ffd166, #ffb84d);
box-shadow: 0 10px 26px rgba(255, 184, 77, .24), inset 0 1px rgba(255,255,255,.5);
transition: transform .18s var(--ease-spring), filter .18s ease, box-shadow .18s ease;
}
.connections-primary-button:not(:disabled):hover {
transform: translateY(-2px) scale(1.01);
filter: brightness(1.06);
box-shadow: 0 14px 34px rgba(255, 184, 77, .32), inset 0 1px rgba(255,255,255,.6);
}
.connections-secondary-button {
color: #dbe7ff;
border: 1px solid #52668d;
background: rgba(24, 36, 67, .82);
transition: transform .18s var(--ease-spring), background .18s ease;
}
.connections-secondary-button:not(:disabled):hover { transform: translateY(-2px); background: #2c3d68; }
.connections-tile {
color: #15213a;
border: 1px solid rgba(255,255,255,.75);
background: linear-gradient(145deg, #fffaf0, #e9effa);
box-shadow: 0 7px 0 #aebbd2, 0 12px 24px rgba(2,8,23,.24), inset 0 1px #fff;
animation: connectionsTileIn .36s var(--ease-spring) both;
transition: transform .16s var(--ease-spring), box-shadow .16s ease, color .16s ease, background .16s ease;
}
.connections-tile:hover { transform: translateY(-3px); box-shadow: 0 9px 0 #aebbd2, 0 16px 30px rgba(2,8,23,.28), inset 0 1px #fff; }
.connections-tile.is-selected {
color: #fff;
border-color: #8c7cf7;
background: linear-gradient(145deg, #735df2, #5540ca);
box-shadow: 0 5px 0 #30228e, 0 12px 28px rgba(84,64,202,.4), inset 0 1px rgba(255,255,255,.28);
transform: translateY(2px) scale(.975);
animation: connectionsTileSelect .25s var(--ease-spring);
}
.connections-group,
.connections-review-card {
color: #172033;
box-shadow: inset 0 1px rgba(255,255,255,.55), 0 10px 26px rgba(2,8,23,.2);
}
.connections-group .text-text-heading,
.connections-group .text-text-secondary,
.connections-review-card .text-text-heading,
.connections-review-card .text-text-secondary { color: #172033; }
.connections-group { animation: connectionsGroupReveal .56s var(--ease-spring) both; }
.connections-group-0 { background: linear-gradient(135deg, #ffd166, #f7b944); }
.connections-group-1 { background: linear-gradient(135deg, #70e1a1, #36bd7c); }
.connections-group-2 { background: linear-gradient(135deg, #72d5f7, #4aa8e8); }
.connections-group-3 { background: linear-gradient(135deg, #b9a2ff, #8d73ed); }
.connections-results-hero {
background: linear-gradient(130deg, #5b46d8, #283d77 58%, #164e63);
box-shadow: inset 0 1px rgba(255,255,255,.18), 0 22px 50px rgba(2,8,23,.3);
}
.connections-completion {
position: relative;
display: grid;
min-height: 32rem;
place-content: center;
overflow: hidden;
border-radius: 1.75rem;
text-align: center;
background: radial-gradient(circle, rgba(94,234,212,.2), transparent 42%), rgba(10,18,39,.72);
animation: connectionsCompletionIn .55s var(--ease-spring) both;
}
.connections-completion-mark {
display: grid;
width: 6rem;
height: 6rem;
margin: 0 auto 1.5rem;
place-items: center;
border-radius: 999px;
color: #172033;
background: #ffd166;
box-shadow: 0 0 0 12px rgba(255,209,102,.12), 0 0 65px rgba(255,209,102,.46);
font-size: 3rem;
font-weight: 900;
animation: connectionsWinMark .8s .15s var(--ease-spring) both;
}
.connections-completion p { color: #8ee7d1; font-size: .75rem; font-weight: 850; letter-spacing: .2em; text-transform: uppercase; }
.connections-completion h2 { margin-top: .35rem; color: white; font-size: clamp(2.5rem, 8vw, 5.5rem); font-weight: 900; letter-spacing: -.065em; line-height: .95; }
.connections-completion span { margin-top: 1rem; color: #b9c8e5; font-weight: 700; }
.connections-confetti { position: absolute; inset: 0; pointer-events: none; }
.connections-confetti i {
position: absolute;
top: -8%;
left: var(--confetti-x);
width: 9px;
height: 17px;
border-radius: 2px;
background: var(--confetti-color);
animation: connectionsConfettiFall 1.45s var(--confetti-delay) cubic-bezier(.2,.7,.3,1) both;
}
@keyframes connectionsTileIn { from { opacity: 0; transform: translateY(16px) scale(.94); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes connectionsTileSelect { 0% { transform: scale(1); } 55% { transform: translateY(3px) scale(.94); } 100% { transform: translateY(2px) scale(.975); } }
@keyframes connectionsShake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-9px); } 40% { transform: translateX(8px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(3px); } }
@keyframes connectionsGroupReveal { from { opacity: 0; transform: scale(.9) translateY(18px); filter: brightness(1.6); } 65% { transform: scale(1.025) translateY(-2px); } to { opacity: 1; transform: scale(1) translateY(0); filter: brightness(1); } }
@keyframes connectionsCompletionIn { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: scale(1); } }
@keyframes connectionsWinMark { from { opacity: 0; transform: scale(.2) rotate(-25deg); } 70% { transform: scale(1.12) rotate(4deg); } to { opacity: 1; transform: scale(1) rotate(0); } }
@keyframes connectionsConfettiFall { 0% { opacity: 0; transform: translateY(-1rem) rotate(0); } 10% { opacity: 1; } 100% { opacity: 1; transform: translateY(38rem) rotate(var(--confetti-spin)); } }
@keyframes connectionsResultsIn { from { opacity: 0; transform: translateY(22px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.animate-connections-shake { animation: connectionsShake .42s ease-in-out; }
.animate-connections-results-in { animation: connectionsResultsIn .52s var(--ease-spring) both; }
.markdown-content h1 { font-size: 1.5rem; font-weight: 700; margin-bottom: .5rem; color: var(--color-text-heading); }
.markdown-content h2 { font-size: 1.25rem; font-weight: 650; margin-bottom: .5rem; color: var(--color-text-heading); }
.markdown-content h3 { font-size: 1.125rem; font-weight: 650; margin-bottom: .5rem; color: var(--color-text-heading); }