@property --accent {
  syntax: '<color>';
  inherits: true;
  initial-value: #5eead4;
}
@property --on-accent {
  syntax: '<color>';
  inherits: true;
  initial-value: #0b0d12;
}

:root {
  --bg: #0b0d12;
  --fg: #e7ebf0;
  --muted: #8b94a3;
  --border: rgba(255, 255, 255, 0.09);
  --accent: #5eead4;
  --on-accent: #0b0d12;

  --chip: clamp(56px, 15.5vw, 64px);
  --d: min(92vw, 64svh);
  --hub-d: calc(var(--d) - var(--chip) * 2 - 22px);

  color-scheme: dark;
  transition: --accent 520ms ease, --on-accent 520ms ease;
}

@media (min-width: 768px) {
  :root {
    --chip: clamp(72px, 6vw, 84px);
    --d: min(560px, 70vh);
  }
}

@media (max-height: 520px) and (orientation: landscape) {
  :root {
    --chip: 48px;
    --d: min(86vw, 74svh);
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--fg);
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; }

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Background: aurora, dot grid, parallax layers ---------- */

.bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  --rgb0: 94 234 212;
  --rgb1: 94 234 212;
  contain: strict;
}

.bg__layer {
  position: absolute;
  inset: 0;
  will-change: transform;
}

.blob {
  position: absolute;
  width: min(max(110vmin, 75vmax), 1500px);
  aspect-ratio: 1;
  will-change: transform;
}

.blob i {
  position: absolute;
  inset: 0;
  transition: opacity 800ms ease;
}

.blob--a { left: -28%; top: -22%; animation: drift-a 38s ease-in-out infinite alternate; }
.blob--b { right: -34%; bottom: -26%; width: min(max(95vmin, 65vmax), 1300px); animation: drift-b 46s ease-in-out infinite alternate; }

.blob--c {
  left: 12%;
  top: 22%;
  width: max(80vmin, 55vmax);
  background: radial-gradient(closest-side, rgb(70 92 170 / 0.17), rgb(70 92 170 / 0.06) 55%, transparent 100%);
}

.blob--a .t0 { background: radial-gradient(closest-side, rgb(var(--rgb0) / 0.26), rgb(var(--rgb0) / 0.1) 50%, transparent 100%); }
.blob--a .t1 { background: radial-gradient(closest-side, rgb(var(--rgb1) / 0.26), rgb(var(--rgb1) / 0.1) 50%, transparent 100%); }
.blob--b .t0 { background: radial-gradient(closest-side, rgb(var(--rgb0) / 0.17), rgb(var(--rgb0) / 0.07) 50%, transparent 100%); }
.blob--b .t1 { background: radial-gradient(closest-side, rgb(var(--rgb1) / 0.17), rgb(var(--rgb1) / 0.07) 50%, transparent 100%); }

.bg[data-tint="0"] .t1,
.bg[data-tint="1"] .t0 { opacity: 0; }

/* The shader canvas (fx.bundle.js). Created by JS and inserted under .dots, so
   it covers the blobs and sits beneath the dot grid. It is absent entirely
   unless the GPU path is taken -- see src/fx.js. */
#fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Hand the background over to the canvas only once it is actually drawing.
   Until .fx-live lands -- no WebGPU, bundle never loaded, device lost, GPU
   start-up failed -- the CSS aurora below is what the visitor sees, unchanged.
   The blobs are faded rather than removed so a device-loss rebuild can bring
   the canvas back without re-running their entrance. */
.bg.fx-live .blob { opacity: 0; }
.blob { transition: opacity 800ms ease; }

.dots {
  position: absolute;
  inset: -4% 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.55) 1px, transparent 1.4px);
  background-size: 26px 26px;
  opacity: 0.09;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 38%, #000 10%, transparent 78%);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 38%, #000 10%, transparent 78%);
}

@keyframes drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to { transform: translate3d(6%, 5%, 0) scale(1.07); }
}
@keyframes drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.04); }
  to { transform: translate3d(-6%, -4%, 0) scale(1); }
}

/* ---------- Main screen ---------- */

.stage {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  justify-items: center;
  padding: env(safe-area-inset-top) 0 0;
}

.masthead {
  text-align: center;
  padding: clamp(22px, 5svh, 44px) 1.25rem 0;
  transform-origin: 50% 0;
  will-change: transform, opacity;
}

.masthead h1 {
  font-size: clamp(2rem, 8.4vw, 3.1rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.masthead .dot { color: var(--accent); }

.tagline {
  color: var(--muted);
  margin-top: 0.4rem;
  font-size: clamp(0.92rem, 3.8vw, 1.05rem);
  text-wrap: balance;
}

.count {
  min-height: 1.4rem;
  margin-top: 0.55rem;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.count b { color: var(--fg); font-weight: 600; }

.count .live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 0.45em;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: 0.08em;
}

.wheel-zone {
  align-self: center;
  width: 100%;
  display: grid;
  place-items: center;
  padding: 22px 0 10px;
  position: relative;
}

/*
 * On portrait phones a full-height stage centers the wheel in leftover space,
 * which leaves dead bands above and below it on tall screens. Size to content
 * with steady spacing instead.
 */
@media (max-width: 767px) and (orientation: portrait) {
  .stage {
    min-height: auto;
    grid-template-rows: auto auto auto;
  }
  .wheel-zone {
    padding: clamp(28px, 5svh, 44px) 0 clamp(22px, 4svh, 34px);
  }
}

.wheel {
  position: relative;
  width: var(--d);
  height: var(--d);
  visibility: hidden;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  cursor: grab;
}

html.ready .wheel { visibility: visible; }
.wheel.is-dragging { cursor: grabbing; }

.wheel__track {
  position: absolute;
  inset: calc(var(--chip) / 2 + 4px);
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.025) 70%, transparent 100%);
}

.wheel__notch {
  position: absolute;
  left: 50%;
  top: -15px;
  width: 14px;
  height: 11px;
  margin-left: -7px;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  z-index: 3;
  will-change: transform;
}

/* The icon band. touch-action none lives here and only here (see .hub). */
.ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  touch-action: none;
}

.opt {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--chip);
  height: var(--chip);
  margin: calc(var(--chip) / -2) 0 0 calc(var(--chip) / -2);
  border-radius: 30%;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.035));
  border: 1px solid rgba(255, 255, 255, 0.13);
  opacity: 0;
  will-change: transform, opacity;
  outline: none;
  cursor: pointer;
  touch-action: none;
}

.opt img {
  width: 62%;
  height: 62%;
  object-fit: contain;
  pointer-events: none;
  -webkit-user-drag: none;
}

.opt .emoji {
  font-size: calc(var(--chip) * 0.46);
  line-height: 1;
  pointer-events: none;
}

.opt__ring {
  position: absolute;
  inset: -6px;
  border-radius: calc(var(--chip) * 0.3 + 6px);
  border: 2px solid var(--c, var(--accent));
  opacity: 0;
  pointer-events: none;
}

.opt:focus-visible::after {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: calc(var(--chip) * 0.3 + 10px);
  outline: 2px dashed #fff;
  outline-offset: 0;
}

/* ---------- Hub ---------- */

.hub {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--hub-d);
  height: var(--hub-d);
  margin: calc(var(--hub-d) / -2) 0 0 calc(var(--hub-d) / -2);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 22%, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.02) 62%),
    rgba(11, 13, 18, 0.5);
  border: 1px solid var(--border);
  container-type: size;
  touch-action: pan-y;
  z-index: 2;
  cursor: default;
}

.panel {
  position: absolute;
  inset: 0;
  padding: 0 10cqw;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 1.8cqw;
  opacity: 0;
  transform: translate3d(0, 5px, 0) scale(0.97);
  pointer-events: none;
  transition: opacity 140ms ease, transform 140ms ease;
}

.panel.on {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  transition: opacity 260ms ease 60ms, transform 320ms cubic-bezier(0.2, 0.8, 0.2, 1) 60ms;
}

.hub__logo {
  width: clamp(34px, 19cqw, 68px);
  height: clamp(34px, 19cqw, 68px);
  display: grid;
  place-items: center;
  flex: none;
}

.hub__logo img { width: 100%; height: 100%; object-fit: contain; }
.hub__logo .emoji { font-size: clamp(28px, 15cqw, 54px); line-height: 1; }

.hub__kind {
  font-size: clamp(9px, 3.3cqw, 11.5px);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1;
  margin-top: 1cqw;
}

.hub__name {
  font-size: clamp(15px, 8cqw, 27px);
  font-weight: 750;
  letter-spacing: -0.01em;
  line-height: 1.1;
  max-width: 100%;
  text-wrap: balance;
}

.hub__desc {
  font-size: clamp(11px, 4.6cqw, 15px);
  line-height: 1.32;
  color: var(--muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  text-wrap: pretty;
  max-width: 100%;
}

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  margin-top: 1.6cqw;
  padding: 0.55em 1.25em;
  min-height: 30px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: clamp(11.5px, 4cqw, 14px);
  font-weight: 700;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  transition: transform 160ms ease;
  -webkit-tap-highlight-color: transparent;
}

.cta:hover { transform: translateY(-1px); }
.cta:active { transform: scale(0.97); }
.cta[hidden] { display: none; }

.cta--soon {
  background: rgba(255, 255, 255, 0.07);
  color: var(--muted);
  border: 1px solid var(--border);
  font-weight: 600;
}

.cta--soon:hover, .cta--soon:active { transform: none; }

/* ---------- Toggle to the list ---------- */

.more {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: max(18px, env(safe-area-inset-bottom));
  padding: 0.6rem 1.1rem;
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.035);
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-decoration: none;
  transition: color 160ms ease, border-color 160ms ease;
}

.more {
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.more:hover { color: var(--fg); border-color: rgba(255, 255, 255, 0.2); }
.more:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.more svg { animation: bob 2.6s ease-in-out infinite; transition: transform 240ms ease; }
.more[aria-expanded="true"] { color: var(--fg); }
.more[aria-expanded="true"] svg { animation: none; transform: rotate(180deg); }

.all[hidden] { display: none; }
.all.is-open { animation: rise 420ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }

@keyframes bob {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50% { transform: translate3d(0, 3px, 0); }
}

/* ---------- Entrance for the readouts ---------- */

html.ready .masthead { animation: rise 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
html.ready .more { animation: rise 600ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms both; }

@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to { opacity: 1; transform: none; }
}

/* ---------- All projects list ---------- */

.all {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 3.2rem 1.25rem 0;
  min-height: 32rem;
}

.all__title {
  font-size: 1.5rem;
  font-weight: 750;
  letter-spacing: -0.02em;
  margin-bottom: 1.6rem;
}

.group + .group { margin-top: 2.2rem; }

.group__title {
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin: 0 0 0.7rem 0.15rem;
}

.list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
  gap: 0.7rem;
}

.row {
  display: flex;
  align-items: center;
  gap: 0.95rem;
  padding: 0.85rem 1rem;
  height: 100%;
  border-radius: 16px;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  color: inherit;
  transition: background-color 160ms ease, border-color 160ms ease;
}

a.row:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.2); }

.row--soon { opacity: 0.62; }

.row__icon {
  flex: none;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.05);
  font-size: 22px;
  line-height: 1;
}

.row__icon img { width: 26px; height: 26px; object-fit: contain; }

.row__text { min-width: 0; flex: 1; display: grid; gap: 0.1rem; }
.row__name { font-weight: 650; font-size: 0.98rem; }
.row__desc { color: var(--muted); font-size: 0.85rem; line-height: 1.4; text-wrap: pretty; }
.row__go { flex: none; color: var(--muted); font-size: 1rem; }

.badge {
  flex: none;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background: rgba(94, 234, 212, 0.14);
  color: #5eead4;
}

.fallback,
.status {
  color: var(--muted);
  font-size: 0.95rem;
  text-align: center;
  text-wrap: balance;
}

.fallback { text-align: left; padding: 0.4rem 0.15rem; }
.fallback a, .status a { color: var(--accent); }

.status {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.9rem;
  padding: 0 1.5rem;
}

.status[hidden] { display: none; }

.status button {
  font: inherit;
  font-weight: 650;
  font-size: 0.85rem;
  color: var(--on-accent);
  background: var(--accent);
  border: 0;
  border-radius: 999px;
  padding: 0.6rem 1.2rem;
  min-height: 40px;
  cursor: pointer;
}

footer {
  position: relative;
  z-index: 1;
  margin-top: 3rem;
  padding: 0 1.25rem max(2rem, env(safe-area-inset-bottom));
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
}

footer a { color: var(--accent); text-decoration: none; }
footer a:hover { text-decoration: underline; }

/* ---------- Reduced motion: no drift, parallax, entrance or crossfade ---------- */

@media (prefers-reduced-motion: reduce) {
  :root { transition: none; }
  .blob--a, .blob--b, .more svg, .all.is-open { animation: none; }
  .more svg { transition: none; }
  .blob i { transition: none; }
  .blob { transition: none; }
  html.ready .masthead, html.ready .more { animation: none; }
  .panel, .panel.on { transition: none; }
  .cta { transition: none; }
}
