:root {
  --bg: #0a0a0a;
  --bg-2: #141414;
  --ink-free: #c9c4b2;
  --ink-captured: #ffffff;
  --glow-captured: 0 0 10px rgba(255, 255, 255, 0.55), 0 0 22px rgba(255, 240, 200, 0.15);
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --letter-size: clamp(22px, 2.4vw, 36px);
  --letter-line: 1.6;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  font-family: var(--font-mono);
  background:
    radial-gradient(ellipse at 50% 35%, var(--bg-2) 0%, var(--bg) 75%),
    var(--bg);
  color: var(--ink-free);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

.stage {
  position: fixed;
  inset: 0;
  cursor: crosshair;
}

/* ----- Scrollable site (index.html) -----
   The messages page stays fixed and no-scroll. Pages that want to scroll opt in
   with class="site" on <html>: the letter hero is pinned to the viewport and a
   tall, transparent .below gives the page its scroll height. */
html.site,
html.site body {
  overflow: visible;
  height: auto;
}
html.site {
  overflow-x: hidden;
  overflow-y: auto;
}

.hero {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

/* The ocean (ocean.html in an iframe) sits fixed behind the page, above the
   letter hero. It runs in embedded mode (transparent above the crest) and the
   host drives its water level, so it rises into view as the letters sweep up -
   no clipping needed; the topmost wave crest is the visible edge. */
.ocean-bg {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}
.ocean-bg iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The section below the hero. Transparent so the fixed ocean shows through; its
   height sets the scroll: the first ~1.25 screens sweep the letters / raise the
   ocean, the rest is room to scroll through the ocean (future content sits here,
   above the ocean at z-index 2). The fixed hero takes no flow space, so this
   block alone sets the page's scroll height. */
.ocean-section {
  position: relative;
  z-index: 2;
  height: 325vh;
}

/* Centered message layout: invisible text that exists only to give the floating
   letters slot positions to form into. Used by both index.html and messages.html. */
.message {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(90vw, 900px);
  padding: 0 clamp(16px, 4vw, 48px);
  font-family: var(--font-mono);
  font-size: var(--letter-size);
  line-height: var(--letter-line);
  letter-spacing: 0.02em;
  text-align: center;
  color: transparent;
  white-space: pre-wrap;
  word-break: normal;
  overflow-wrap: break-word;
  user-select: none;
  pointer-events: none;
  z-index: 2;
}

.message .char {
  display: inline-block;
  width: 1ch;
  text-align: center;
}

.message .space {
  display: inline;
  white-space: pre;
}

.floaters {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  contain: strict;
}

.floater {
  position: absolute;
  top: 0;
  left: 0;
  font-family: var(--font-mono);
  font-size: var(--letter-size);
  line-height: 1;
  color: var(--ink-free);
  opacity: 0.8;
  pointer-events: none;
  will-change: transform;
  text-shadow: 0 0 1px rgba(255, 255, 255, 0.08);
  user-select: none;
}

/* Captured letters keep the same hue; messages.js raises their opacity and adds
   a soft glow by proximity, so a forming message brightens toward the center. */
.floater.is-captured {
  color: var(--ink-free);
}

@media (prefers-reduced-motion: reduce) {
  .floater { transition-duration: 120ms; }
}

@media (max-width: 600px) {
  :root {
    --letter-size: 18px;
    --letter-line: 1.55;
  }
}
