/* One centered column over a full-bleed WebGL scene (scene.js): chrome logo on top, a tilting frosted
   link menu below. Dark only: the chrome's reflections and glow are lit for a dark room. */
:root {
  color-scheme: dark;
  --bg: #07080A;
  --fg: #F2F3F5;
  --muted: #8C9099;
  --muted-hi: #C6CAD1;
  --hair: rgba(255, 255, 255, .09);
  --divider: rgba(255, 255, 255, .07);
  --hover: rgba(255, 255, 255, .035);
  --sheen: rgba(255, 255, 255, .06);
  --rim: rgba(255, 255, 255, .07);
  --dot: #DCE3EE;
  --panel: rgba(0, 0, 0, .02);
  /* Neutral silver accent. */
  --accent: #D3D7DD;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Eased cursor offset from center, -1…1, written each frame by main.js. */
  --px: 0;
  --py: 0;
}

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--bg); }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(72px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(48px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
  color: var(--fg);
  font-family: var(--mono);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-x: clip;
}

a { color: inherit; text-decoration: none; }

@keyframes fade-in { from { opacity: 0; } }

/* WebGL canvas behind everything; its `color` hands the star color to scene.js. */
.gl {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  color: var(--dot);
}

/* Layout */
.page {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 480px;
}

.head { display: flex; justify-content: center; }

.brand { margin: 0; font-size: inherit; line-height: 0; }

.logo-slot {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 220px;
  height: 49px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--fg);
  cursor: pointer;
}
.logo-slot:focus-visible { outline: 1px solid var(--accent); outline-offset: 16px; }

.logo-fallback { display: block; width: 100%; height: 100%; transition: opacity .6s ease; }
.gl-ready .logo-fallback { opacity: 0; }

/* One board holds the logo, both section labels and both panels. A single perspective and a single rotation
   (7°/9°, the same the 3D logo uses; scene.js keeps the logo on the board's logo slot) tilt it all as one
   rigid object; section labels, rows, icons and text float at different depths above it. */
.stage { perspective: 1100px; }

.board {
  display: flex;
  flex-direction: column;
  gap: 64px;
  transform: rotateX(calc(var(--py) * -7deg)) rotateY(calc(var(--px) * 9deg));
}
.board,
.board * { transform-style: preserve-3d; }

/* Projects above links, each a labelled frosted panel. */
.sections { display: flex; flex-direction: column; gap: 40px; }

.section { display: flex; flex-direction: column; gap: 14px; }

.section-label {
  margin: 0;
  padding-left: 18px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .24em;
  color: var(--muted);
  transform: translateZ(18px);
  animation: fade-in .8s .5s ease both;
}

.menu { position: relative; display: block; }

.menu-bg {
  position: absolute;
  inset: 0;
  display: block;
  background:
    radial-gradient(440px circle at calc(50% + var(--px) * 70%) calc(50% + var(--py) * 90%), var(--sheen), transparent 65%),
    var(--panel);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: inset 0 0 0 1px var(--rim);
  animation: fade-in .9s .6s ease both;
}

.rows { position: relative; display: flex; flex-direction: column; padding: 14px; }

.row {
  --delay: calc(.78s + var(--i, 0) * .08s);
  position: relative;
  display: flex;
  align-items: stretch;
  transform: translateZ(24px);
  transition: transform .55s var(--ease-out), background-color .3s ease;
  animation: row-in .8s var(--ease-out) var(--delay) both;
}
.row:hover,
.row:focus-within { transform: translateZ(44px); background-color: var(--hover); }
@keyframes row-in { from { opacity: 0; translate: 0 12px; } }

.hair {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: block;
  height: 1px;
  background: var(--hair);
  transform-origin: 0 50%;
  pointer-events: none;
  animation: hair-in 1s var(--ease-in-out) var(--delay) both;
}
.hair-end {
  --delay: calc(.78s + var(--i, 0) * .08s);
  top: auto;
  bottom: 14px;
  left: 14px;
  right: 14px;
  transform: translateZ(24px);
}
@keyframes hair-in { from { scale: 0 1; } }

/* Hover underline: draws in from the left, leaves to the right. */
.sweep {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  z-index: 2;
  display: block;
  height: 1px;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .55s var(--ease-in-out);
  pointer-events: none;
}
.row:hover .sweep,
.row:focus-within .sweep { transform: scaleX(1); transform-origin: 0 50%; }

.link {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 64px;
  padding: 0 10px 0 4px;
  color: var(--fg);
}
.link:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }

/* A row that copies text instead of linking (Discord). */
button.link {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.ic {
  flex: 0 0 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  transform: translateZ(16px);
  transition: color .3s, transform .5s var(--ease-out);
}
.ic svg { width: 18px; height: 18px; }
.row:hover .ic,
.row:focus-within .ic { color: var(--accent); transform: translateZ(26px) rotate(-6deg); }

.label {
  display: inline-block;
  flex: 0 0 auto;
  margin-right: auto;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  white-space: pre;
  transform: translateZ(10px);
  transition: transform .5s var(--ease-out);
}
.row:hover .label,
.row:focus-within .label { transform: translateZ(14px) translateX(6px); }

.meta {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 12px;
  line-height: 1.2;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transform: translateZ(6px);
  transition: color .3s;
}
.row:hover .meta,
.row:focus-within .meta { color: var(--muted-hi); }

.chev {
  flex: 0 0 18px;
  width: 18px;
  height: 18px;
  color: var(--muted);
  transform: translateZ(12px);
  transition: transform .5s var(--ease-out), color .3s;
}
.chev path { transition: opacity .3s, transform .5s var(--ease-out); }
.chev path:last-child { opacity: .4; }
.row:hover .chev,
.row:focus-within .chev { transform: translateZ(18px) translateX(4px); color: var(--accent); }
.row:hover .chev path:last-child,
.row:focus-within .chev path:last-child { opacity: 1; transform: translateX(2px); }

/* Project rows: a framed mark, then the name over what it does. */
.project .link { min-height: 76px; padding-block: 14px; }

.mark {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  border: 1px solid var(--rim);
  background: rgba(255, 255, 255, .025);
}
.row:hover .mark,
.row:focus-within .mark { border-color: rgba(211, 215, 221, .35); transform: translateZ(28px); }

.stack { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; }

.desc {
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
  transform: translateZ(6px);
  transition: color .3s;
}
.row:hover .desc,
.row:focus-within .desc { color: var(--muted-hi); }

.hint {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .08em;
  color: var(--muted);
  transform: translateZ(12px);
  transition: color .3s;
}
.row:hover .hint,
.row:focus-within .hint { color: var(--fg); }
.row .hint.is-done { color: var(--accent); }

.copy {
  flex: 0 0 auto;
  min-width: 76px;
  min-height: 64px;
  padding: 0 14px;
  border: 0;
  border-left: 1px solid var(--divider);
  background: transparent;
  color: var(--muted);
  font: 500 11px/1 var(--mono);
  letter-spacing: .08em;
  cursor: pointer;
  transform: translateZ(8px);
  transition: color .25s;
}
.copy[hidden] { display: none; }
.copy:hover { color: var(--fg); }
.copy.is-done { color: var(--accent); }
.copy:focus-visible { outline: 1px solid var(--accent); outline-offset: -1px; }

/* Browsers don't antialias the edges of 3D-transformed layers, so a hairline, rim or border that lies on a
   layer's edge stair-steps once the board tilts. A transparent outline grows each layer by a pixel, which puts
   those lines inside it, where they are smoothly filtered. */
.menu-bg,
.row,
.hair,
.sweep,
.mark,
.copy,
.section-label { outline: 1px solid transparent; }

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
