:root { --bg: oklch(97% 0.018 70); --surface: oklch(99% 0.008 70); --fg: oklch(22% 0.02 50); --muted: oklch(50% 0.018 50); --border: oklch(90% 0.014 70); --accent: oklch(64% 0.13 28); --font-display: 'Tiempos Headline', 'Newsreader', 'Iowan Old Style', Georgia, serif; --font-body: 'Söhne', -apple-system, BlinkMacSystemFont, system-ui, sans-serif; --correct: oklch(59% 0.12 145); --present: oklch(73% 0.12 82); --absent: oklch(47% 0.018 50); --tile: oklch(99% 0.008 70); --key: oklch(91% 0.018 70); --shadow: 0 24px 80px oklch(22% 0.02 50 / 0.12); } *, *::before, *::after { box-sizing: border-box; } html { min-height: 100%; } body { min-height: 100vh; margin: 0; background: radial-gradient(circle at 12% 0%, oklch(88% 0.065 45 / 0.35), transparent 34rem), var(--bg); color: var(--fg); font-family: var(--font-body); text-align: center; } body.dark-theme { --bg: oklch(18% 0.018 50); --surface: oklch(24% 0.018 50); --fg: oklch(96% 0.014 70); --muted: oklch(76% 0.014 70); --border: oklch(33% 0.018 50); --tile: oklch(26% 0.018 50); --key: oklch(34% 0.018 50); --shadow: 0 24px 80px oklch(8% 0.01 50 / 0.38); } body.intro-active { overflow: hidden; } body.intro-active .app-shell { pointer-events: none; user-select: none; } .intro-overlay { --intro-bg: #111111; --intro-fg: #fafafa; --intro-border: #e5e5e5; --intro-accent: #2f6feb; --intro-tile-empty: #3a3a3c; --intro-tile-wrong: #787c7e; --intro-tile-misplaced: #c9b458; --intro-tile-correct: #6aaa64; --intro-font-mono: ui-monospace, "JetBrains Mono", monospace; position: fixed; inset: 0; z-index: 1000; display: grid; min-block-size: 100svh; place-items: center; overflow: hidden; background: linear-gradient(180deg, #181818 0%, var(--intro-bg) 58%, #080808 100%); color: var(--intro-fg); font-family: var(--font-body); opacity: 1; perspective: 1200px; transition: opacity 520ms ease, visibility 520ms ease; visibility: visible; } .intro-overlay::before, .intro-overlay::after { content: ""; position: absolute; inset-inline: 0; block-size: 20vh; z-index: 4; pointer-events: none; } .intro-overlay::before { inset-block-start: 0; background: linear-gradient(180deg, rgba(17, 17, 17, 0.85), transparent); } .intro-overlay::after { inset-block-end: 0; background: linear-gradient(0deg, rgba(17, 17, 17, 0.88), transparent); } .intro-overlay.is-dismissing { opacity: 0; pointer-events: none; visibility: hidden; } .intro-overlay[hidden] { display: none; } .intro-stage { position: relative; display: grid; inline-size: min(1120px, calc(100vw - 32px)); block-size: min(640px, calc(100svh - 32px)); min-block-size: 420px; place-items: center; transform-style: preserve-3d; } .intro-scanline { position: absolute; inset-inline: 10%; inset-block-start: 50%; z-index: 1; block-size: 1px; background: linear-gradient(90deg, transparent, rgba(250, 250, 250, 0.36), transparent); opacity: 0; transform: translateY(-50%); animation: intro-scan 4.8s ease forwards; } .intro-tiles { --intro-tile-size: clamp(46px, 10vw, 128px); --intro-tile-gap: clamp(6px, 1.4vw, 16px); position: relative; z-index: 2; display: grid; grid-template-columns: repeat(6, var(--intro-tile-size)); gap: var(--intro-tile-gap); transform-origin: 50% 50%; transform-style: preserve-3d; transition: gap 420ms cubic-bezier(0.2, 0.7, 0.15, 1), transform 520ms cubic-bezier(0.2, 0.7, 0.15, 1); } .intro-tile { position: relative; inline-size: var(--intro-tile-size); block-size: var(--intro-tile-size); opacity: 0; transform: translate3d(0, 34px, -180px); transform-style: preserve-3d; animation: intro-tile-enter 520ms cubic-bezier(0.2, 0.7, 0.15, 1) forwards; animation-delay: calc(var(--intro-index) * 56ms); } .intro-letter { position: absolute; inset: 0; display: grid; place-items: center; border: 1px solid rgba(229, 229, 229, 0.18); background: var(--intro-tile-empty); box-shadow: inset 0 0 0 1px rgba(250, 250, 250, 0.08); color: var(--intro-fg); font-family: var(--font-body); font-size: clamp(28px, 6vw, 78px); font-weight: 900; line-height: 1; text-transform: uppercase; transform-origin: 50% 50%; } .intro-tile.is-flipping .intro-letter { animation: intro-split-flap 260ms cubic-bezier(0.3, 0.7, 0.2, 1); } .intro-tile[data-status="wrong"] .intro-letter { background: var(--intro-tile-wrong); } .intro-tile[data-status="misplaced"] .intro-letter { background: var(--intro-tile-misplaced); } .intro-tile[data-status="correct"] .intro-letter { background: var(--intro-tile-correct); } .intro-tile:nth-child(1) { --intro-index: 0; } .intro-tile:nth-child(2) { --intro-index: 1; } .intro-tile:nth-child(3) { --intro-index: 2; } .intro-tile:nth-child(4) { --intro-index: 3; } .intro-tile:nth-child(5) { --intro-index: 4; } .intro-tile:nth-child(6) { --intro-index: 5; } .intro-tiles.is-solved .intro-tile { opacity: 1; animation: intro-logo-cascade 680ms cubic-bezier(0.18, 0.85, 0.22, 1) calc(var(--intro-index) * 76ms) both; } .intro-tiles.is-logo { gap: clamp(3px, 0.7vw, 8px); transform: scale(0.88); } .intro-tiles.is-logo .intro-letter { border-color: rgba(250, 250, 250, 0.28); box-shadow: inset 0 0 0 1px rgba(250, 250, 250, 0.1), 0 0 28px rgba(106, 170, 100, 0.16); } .intro-caption { position: absolute; inset-block-end: clamp(24px, 6vh, 64px); inset-inline: 24px; z-index: 5; display: flex; justify-content: center; color: rgba(250, 250, 250, 0.62); font-family: var(--intro-font-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0; animation: intro-caption-cue 4.8s ease forwards; } .intro-skip { position: fixed; inset-block-start: 16px; inset-inline-end: 16px; z-index: 10; min-height: 40px; border: 1px solid rgba(229, 229, 229, 0.22); border-radius: 999px; padding: 0 16px; background: rgba(17, 17, 17, 0.74); color: var(--intro-fg); cursor: pointer; font: 800 0.85rem/1 var(--font-body); } .intro-skip:hover { border-color: rgba(250, 250, 250, 0.5); } .intro-skip:focus-visible { outline: 2px solid var(--intro-accent); outline-offset: 3px; } .intro-overlay.restarting * { animation: none !important; } button, a { font: inherit; } .app-shell { width: min(1120px, calc(100% - 32px)); min-height: 100vh; margin: 0 auto; padding: 24px 0 32px; } .topbar, .game-card, .stats-card { border: 1px solid var(--border); background: color-mix(in oklch, var(--surface) 90%, transparent); box-shadow: 0 0 0 1px color-mix(in oklch, var(--surface) 70%, transparent); } .topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 68px; padding: 10px 12px; border-radius: 20px; backdrop-filter: blur(18px); } .brand, .actions { display: flex; align-items: center; } .brand { gap: 12px; color: inherit; text-align: start; text-decoration: none; } .brand-mark { display: grid; width: 44px; height: 44px; place-items: center; border-radius: 14px; background: var(--fg); color: var(--surface); font-family: var(--font-display); font-size: 1.35rem; } .brand strong { display: block; font-family: var(--font-display); font-size: 1.15rem; font-weight: 500; } .brand small, .deck, .status-row, .alert { color: var(--muted); } .actions { gap: 8px; } .icon-button, .auth-button, .button { min-width: 44px; min-height: 44px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface); color: var(--fg); cursor: pointer; text-decoration: none; transition: transform 160ms ease, border-color 160ms ease, background-color 160ms ease; } .icon-button { display: inline-grid; place-items: center; font-size: 1.25rem; } .icon-button:hover, .auth-button:hover, .button:hover { transform: translateY(-1px); border-color: color-mix(in oklch, var(--accent), var(--border) 45%); } .game-card { display: grid; grid-template-columns: minmax(280px, 0.9fr) minmax(320px, 1.1fr); gap: clamp(20px, 4vw, 56px); margin-top: 18px; padding: clamp(20px, 4vw, 48px); border-radius: 32px; box-shadow: var(--shadow); } .hero-panel { display: flex; flex-direction: column; justify-content: center; text-align: start; } .eyebrow { margin: 0 0 12px; color: var(--accent); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; } h1, h2 { margin: 0; font-family: var(--font-display); font-weight: 500; line-height: 1.05; } h1 { max-width: 9ch; font-size: clamp(3rem, 7vw, 5.9rem); } h2 { font-size: clamp(2rem, 4vw, 3rem); } .deck { max-width: 34rem; margin: 22px 0 0; font-size: clamp(1rem, 1.4vw, 1.2rem); line-height: 1.65; } .board-panel { position: relative; display: grid; justify-items: center; gap: 18px; min-width: 0; } .status-row { display: flex; width: min(100%, 430px); align-items: center; justify-content: space-between; gap: 12px; font-size: 0.9rem; } .pill { padding: 6px 10px; border: 1px solid var(--border); border-radius: 999px; color: var(--fg); font-variant-numeric: tabular-nums; } .guess-grid { display: grid; grid-template-columns: repeat(5, minmax(44px, 68px)); grid-template-rows: repeat(6, minmax(44px, 68px)); gap: 8px; inline-size: min(100%, 372px); aspect-ratio: 5 / 6; } .tile { display: grid; place-items: center; border: 1px solid var(--border); border-radius: 14px; background: var(--tile); color: var(--fg); font-size: clamp(1.35rem, 5vw, 2rem); font-weight: 800; text-transform: uppercase; user-select: none; transition: transform 250ms ease, background-color 160ms ease, color 160ms ease, border-color 160ms ease; } .tile[data-state="active"] { border-color: color-mix(in oklch, var(--accent), var(--fg) 25%); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent), transparent 60%); } .tile[data-state="wrong"], .key.wrong { background: var(--absent); border-color: var(--absent); color: white; } .tile[data-state="wrong-position"], .key.wrong-position { background: var(--present); border-color: var(--present); color: var(--fg); } .tile[data-state="correct"], .key.correct { background: var(--correct); border-color: var(--correct); color: white; } .tile.flip { transform: rotateX(90deg); } .tile.shake { animation: shake 250ms ease-in-out; } .tile.dance { animation: dance 500ms ease-in-out; } .keyboard { display: grid; grid-template-columns: repeat(20, minmax(0, 1fr)); gap: 6px; width: min(100%, 560px); touch-action: manipulation; } .key { grid-column: span 2; min-height: 48px; padding: 0; border: 1px solid color-mix(in oklch, var(--border), var(--fg) 5%); border-radius: 12px; background: var(--key); color: var(--fg); font-size: clamp(0.8rem, 2vw, 1rem); font-weight: 800; cursor: pointer; user-select: none; } .key.large { grid-column: span 3; font-size: 0.78rem; } .key.space { grid-column: span 1; visibility: hidden; } .key svg { width: 1.35rem; height: 1.35rem; fill: currentColor; } .key:hover, .key:focus-visible { outline: none; transform: translateY(-1px); border-color: var(--accent); } .alert-container { position: fixed; inset-block-start: 96px; inset-inline: 16px; z-index: 10; display: grid; justify-items: center; gap: 8px; pointer-events: none; } .alert { max-width: min(440px, calc(100vw - 32px)); padding: 12px 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow); color: var(--fg); line-height: 1.45; opacity: 1; transition: opacity 400ms ease, transform 400ms ease; } .alert.hide { opacity: 0; transform: translateY(-6px); } .stats-modal { width: min(520px, calc(100vw - 32px)); padding: 0; border: 0; border-radius: 24px; background: transparent; color: var(--fg); } .stats-modal::backdrop { background: oklch(18% 0.018 50 / 0.45); backdrop-filter: blur(4px); } .stats-card { padding: 22px; border-radius: 24px; text-align: start; } .modal-head, .modal-actions, .stat-item, .guess-bar { display: flex; align-items: center; } .modal-head, .modal-actions { justify-content: space-between; gap: 16px; } .close-button { flex: 0 0 auto; } .stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 22px 0; } .stat-item { min-height: 82px; flex-direction: column; justify-content: center; border: 1px solid var(--border); border-radius: 16px; background: var(--bg); } .stat-item strong { font-family: var(--font-display); font-size: 2rem; font-weight: 500; } .stat-item span { color: var(--muted); font-size: 0.78rem; } .guess-bars { display: grid; gap: 8px; margin-bottom: 22px; } .stats-note, .leaderboard-countdown { margin: -8px 0 18px; color: var(--muted); font-size: 0.9rem; line-height: 1.5; } .leaderboard-result { display: grid; gap: 12px; padding: 14px; border: 1px solid color-mix(in oklch, var(--accent), var(--border) 45%); border-radius: 16px; background: color-mix(in oklch, var(--accent), var(--surface) 88%); color: var(--fg); line-height: 1.55; } .leaderboard-result[hidden] { display: none; } .leaderboard-result-summary { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; border-bottom: 1px solid color-mix(in oklch, var(--accent), var(--border) 62%); padding-bottom: 10px; } .leaderboard-result strong { display: block; font-family: var(--font-display); font-size: 1.35rem; font-weight: 500; } .leaderboard-result span { color: var(--muted); } .leaderboard-result-summary span { flex: 0 0 auto; font-size: 0.9rem; font-weight: 900; } .leaderboard-definition { display: grid; gap: 6px; } .leaderboard-result em { display: block; margin-top: 10px; color: var(--muted); font-style: normal; } .definition-panel { display: grid; gap: 10px; margin-bottom: 22px; } .definition-panel h3 { margin: 0; font-family: var(--font-display); font-size: 1.15rem; font-weight: 500; } .stats-definition { padding: 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--bg); color: var(--muted); line-height: 1.55; text-align: start; } .stats-definition strong { display: block; margin-bottom: 6px; color: var(--fg); font-family: var(--font-display); font-size: 1.35rem; font-weight: 500; line-height: 1.1; } .stats-definition .word-label { font-family: var(--font-body); font-size: 0.76rem; font-weight: 900; letter-spacing: 0.08em; text-transform: uppercase; } .stats-definition em { display: block; margin-top: 10px; color: var(--muted); font-style: normal; } .leaderboard-card { display: grid; gap: 18px; } .leaderboard-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } .leaderboard-tab { min-height: 38px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg); color: var(--fg); cursor: pointer; font-size: 0.82rem; font-weight: 900; } .leaderboard-tab.active { border-color: var(--accent); background: var(--accent); color: white; } .leaderboard-list { display: grid; gap: 10px; } .leaderboard-row, .leaderboard-empty { border: 1px solid var(--border); border-radius: 16px; background: var(--bg); } .leaderboard-row { display: grid; grid-template-columns: 2.4rem 1fr auto; align-items: center; gap: 12px; min-height: 58px; padding: 10px 12px; } .leaderboard-row.you { border-color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent), transparent 60%); } .leaderboard-rank { display: grid; width: 2.1rem; height: 2.1rem; place-items: center; border-radius: 999px; background: var(--fg); color: var(--surface); font-family: var(--font-display); } .leaderboard-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 800; } .leaderboard-streak { display: block; color: var(--muted); font-size: 0.76rem; font-weight: 700; } .leaderboard-score { color: var(--muted); font-size: 0.86rem; font-variant-numeric: tabular-nums; } .leaderboard-empty { padding: 18px; color: var(--muted); line-height: 1.55; } .guess-bar { gap: 10px; } .guess-bar-label { width: 1.5rem; color: var(--muted); font-variant-numeric: tabular-nums; } .guess-bar-fill { min-width: 28px; height: 26px; padding-inline-end: 8px; border-radius: 8px; background: color-mix(in oklch, var(--accent), var(--border) 40%); color: white; text-align: end; font-size: 0.8rem; font-weight: 800; line-height: 26px; } .button { padding: 0 16px; font-weight: 700; } .auth-button { padding: 0 14px; font-size: 0.88rem; font-weight: 800; } .full-width { width: 100%; } .button.primary { background: var(--accent); color: white; } .button.secondary { background: var(--key); } .auth-card { display: grid; gap: 16px; } .auth-status { margin: 0; color: var(--muted); line-height: 1.55; } .auth-form { display: grid; gap: 10px; } .auth-form[hidden], .auth-create-fields[hidden], .button[hidden] { display: none; } .auth-create-fields { display: grid; gap: 10px; } .auth-reset-fields { display: grid; gap: 10px; margin-top: 4px; } .auth-reset-fields[hidden] { display: none; } .account-summary { display: grid; gap: 4px; padding: 14px; border: 1px solid var(--border); border-radius: 16px; background: var(--bg); } .account-summary[hidden] { display: none; } .account-summary strong { font-family: var(--font-display); font-size: 1.25rem; font-weight: 500; } .account-summary span { color: var(--muted); font-size: 0.85rem; } .auth-form label { color: var(--muted); font-size: 0.82rem; font-weight: 800; } .optional-label { font-weight: 600; opacity: 0.72; } .auth-form input { min-height: 46px; width: 100%; border: 1px solid var(--border); border-radius: 14px; background: var(--bg); color: var(--fg); font: inherit; padding: 0 14px; } .auth-button-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 4px; } .auth-button-row .button:only-child, .auth-button-row .button[hidden] + .button, .auth-button-row .button:first-child:last-child { grid-column: 1 / -1; } .auth-button-row:not(:has(#auth-sign-up:not([hidden]))) #auth-sign-in { grid-column: 1 / -1; } .auth-form input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent), transparent 75%); } .auth-actions { margin: 0; padding: 0; } .link-button { width: max-content; border: 0; background: transparent; color: var(--accent); cursor: pointer; font-weight: 800; padding: 0; text-align: start; } @keyframes intro-tile-enter { 0% { transform: translate3d(0, 34px, -180px); filter: blur(2px); opacity: 0; } 100% { transform: translate3d(0, 0, 0); filter: blur(0); opacity: 1; } } @keyframes intro-split-flap { 0% { transform: rotateX(0deg); filter: brightness(1); } 49% { transform: rotateX(-88deg); filter: brightness(0.72); } 50% { transform: rotateX(88deg); filter: brightness(1.12); } 100% { transform: rotateX(0deg); filter: brightness(1); } } @keyframes intro-logo-cascade { 0% { transform: translate3d(0, 0, 0) scale(1); filter: brightness(1); } 34% { transform: translate3d(0, -22%, 130px) scale(1.18); filter: brightness(1.16); } 62% { transform: translate3d(0, 4%, 0) scale(0.98); filter: brightness(1.04); } 100% { transform: translate3d(0, 0, 0) scale(1); filter: brightness(1); } } @keyframes intro-scan { 0%, 12% { opacity: 0; transform: translateY(-50%) scaleX(0.2); } 24% { opacity: 0.75; } 54% { opacity: 0.22; transform: translateY(-50%) scaleX(1); } 72%, 100% { opacity: 0; } } @keyframes intro-caption-cue { 0%, 18% { opacity: 0; transform: translateY(8px); } 28%, 64% { opacity: 1; transform: translateY(0); } 82%, 100% { opacity: 0; transform: translateY(-8px); } } @keyframes shake { 10%, 90% { transform: translateX(-4%); } 30%, 70% { transform: translateX(5%); } 50% { transform: translateX(-7%); } } @keyframes dance { 20% { transform: translateY(-45%); } 40% { transform: translateY(4%); } 60% { transform: translateY(-20%); } 80% { transform: translateY(2%); } 100% { transform: translateY(0); } } @media (max-width: 720px) { .intro-stage { min-block-size: 420px; } .intro-tiles { --intro-tile-size: min(13.5vw, 56px); --intro-tile-gap: 5px; } .intro-caption { font-size: 10px; } .intro-skip { min-height: 38px; padding-inline: 14px; } } @media (prefers-reduced-motion: reduce) { .intro-overlay, .intro-tiles, .intro-tile, .intro-letter, .intro-scanline, .intro-caption { animation-duration: 1ms !important; animation-delay: 0ms !important; transition-duration: 1ms !important; } } @media (max-width: 780px) { .app-shell { width: min(100% - 20px, 600px); padding-top: 10px; } .game-card { grid-template-columns: 1fr; padding: 18px; border-radius: 24px; } .hero-panel { text-align: center; } h1, .deck { margin-inline: auto; } .deck { margin-top: 12px; } } @media (max-width: 460px) { .brand small { display: none; } .topbar { padding: 8px; } .actions { gap: 4px; } .icon-button { min-width: 40px; min-height: 40px; } .guess-grid { gap: 6px; } .tile { border-radius: 10px; } .keyboard { gap: 4px; } .key { min-height: 44px; border-radius: 9px; } .stats-grid { grid-template-columns: repeat(2, 1fr); } }