@font-face {
  font-family: "Fautive";
  src: url("fonts/fautive-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}
@font-face {
  /* Frank Ruhl Libre, SIL OFL — the Hebrew book serif, so it sits beside
     Sagittaire rather than looking borrowed. Hebrew subset only; the
     unicode-range keeps Latin text from ever falling through to it. */
  font-family: "FrankRuhl";
  src: url("fonts/frankruhllibre-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
  unicode-range: U+0590-05FF, U+FB1D-FB4F, U+200C-200D;
}
@font-face {
  font-family: "Sagittaire";
  src: url("fonts/sagittairetext-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

:root {
  --abyss: #06121f;
  --deep: #0a2a43;
  --mystic: #163e68;
  --aurora: #2f8fa3;
  --red: #d92525;
  --ember: #ff5a36;
  --gold: #ffd27a;
  --ivory: #f3e9dd;
  --mist: #9cb9c9;
  --char: #57201b;
  --serif: "Sagittaire", "Iowan Old Style", Georgia, serif;
  --sans: "Fautive", "Helvetica Neue", Arial, sans-serif;
  --hebrew: "FrankRuhl", "Frank Ruhl Libre", "Arial Hebrew", serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body {
  margin: 0;
  height: 100%;
  height: 100dvh; /* mobile browser chrome must not push the layout off-screen */
  background: var(--abyss);
  color: var(--ivory);
  font-family: var(--sans);
  font-weight: 500;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}
#gl {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}
#vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 55%, rgba(6, 18, 31, 0) 48%, rgba(6, 18, 31, 0.55) 100%);
  z-index: 2;
}
.micro {
  font-size: 12px;
  line-height: 1.3;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mist);
}
button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

/* ------------------------------------------------------------ intention */
.screen {
  position: fixed;
  inset: 0;
  z-index: 5;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.screen.on { opacity: 1; }
.screen.sealing {
  opacity: 0;
  transform: scale(1.5);
  filter: blur(14px);
  transition: opacity 0.55s cubic-bezier(0.7, 0, 0.9, 0.4), transform 0.6s cubic-bezier(0.7, 0, 0.9, 0.4), filter 0.6s ease;
}
#intention {
  display: flex;
  align-items: stretch;
}
/* A scrolling body with a fixed footer, so the primary action is reachable at
   any viewport height without a sticky element floating over the content. */
.panel {
  width: min(560px, 100%);
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 4vh, 56px) clamp(20px, 4vw, 56px) clamp(14px, 2.6vh, 28px);
  background: linear-gradient(90deg, rgba(6, 18, 31, 0.94) 0%, rgba(6, 18, 31, 0.82) 70%, rgba(6, 18, 31, 0) 100%);
}
.panel-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* so the last row does not sit flush against the cut and read as clipped */
  padding-bottom: 10px;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 2.2vh, 22px);
}
.panel-foot {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.6vh, 14px);
  padding-top: clamp(10px, 2vh, 18px);
}
.panel h1 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(34px, 5.6vh, 76px);
  line-height: 0.9;
  letter-spacing: -0.035em;
}
.panel h1 em {
  font-style: normal;
  color: var(--gold);
}
.field {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
textarea {
  width: 100%;
  resize: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--mystic);
  padding: 8px 0 12px;
  color: var(--ivory);
  font: inherit;
  font-size: clamp(20px, 2.4vh, 26px);
  line-height: 1.25;
  letter-spacing: -0.015em;
  outline: none;
  transition: border-color 0.25s;
}
textarea:focus { border-color: var(--red); }
.reduction { display: flex; flex-direction: column; gap: 12px; }
.ops {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--mystic);
  border-bottom: 1px solid var(--mystic);
}
.ops span {
  padding: 8px 0;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mist);
}
.ops span + span { padding-left: 12px; border-left: 1px solid var(--mystic); }
.letter-stream {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 1px;
  min-height: 42px;
  max-height: 22vh;
  overflow-y: auto;
  font-size: clamp(15px, 1.9vh, 19px);
  line-height: 1.15;
}
.sl { width: 1ch; }
.sl { position: relative; min-width: 15px; text-align: center; color: var(--ivory); }
.sl.vowel { color: var(--mist); opacity: 0.3; }
.sl.duplicate { color: var(--ember); opacity: 0.55; }
.sl.duplicate::after {
  content: "";
  position: absolute;
  left: 1px; right: 1px; top: 52%;
  height: 2px;
  background: var(--red);
}
.result {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0 0 14px;
  border-left: 4px solid var(--red);
}
.reduced {
  display: flex;
  flex-wrap: wrap;
  gap: 0 8px;
  font-family: var(--serif);
  font-size: clamp(26px, 3.4vh, 36px);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--gold);
}
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  padding-top: 14px;
  border-top: 1px solid var(--mystic);
}
.stats div { display: flex; flex-direction: column; gap: 6px; }
.stats strong {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.seal {
  align-self: stretch;
  border: 0;
  background: var(--red);
  color: var(--ivory);
  font-family: var(--serif);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: -0.02em;
  padding: 16px 30px 17px;
  box-shadow: 0 0 34px rgba(217, 37, 37, 0.35);
  transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
}
.seal:hover:not(:disabled) { background: var(--ember); box-shadow: 0 0 44px rgba(255, 90, 54, 0.45); transform: translateY(-1px); }
.seal:disabled { background: var(--mystic); color: var(--mist); box-shadow: none; cursor: not-allowed; }
.legend {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  font-size: 11px; letter-spacing: 0.12em;
}
.legend b { color: var(--ivory); font-weight: 500; }

/* ------------------------------------------------------------------ hud */
#hud {
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.hud-tl { position: absolute; left: 32px; top: 28px; max-width: min(560px, 60vw); display: flex; flex-direction: column; gap: 10px; }
.intention-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.letters {
  display: flex;
  flex-wrap: wrap;
  gap: 0 5px;
  font-family: var(--serif);
  font-size: 26px;
  line-height: 1;
  letter-spacing: 0.02em;
}
.letters span { transition: color 0.3s, text-shadow 0.3s, opacity 0.3s; }
.letters .cold { color: var(--mist); opacity: 0.45; }
.letters .lit { color: var(--ivory); opacity: 1; }
.letters .good { color: var(--ember); opacity: 1; text-shadow: 0 0 14px rgba(255, 90, 54, 0.6); }
.letters .perfect { color: var(--gold); opacity: 1; text-shadow: 0 0 18px rgba(255, 210, 122, 0.75); }
.letters .snapped { color: var(--red); opacity: 0.9; }
.letters .missed { color: var(--char); opacity: 0.9; }
.hud-tr { position: absolute; right: 32px; top: 22px; text-align: right; }
.time {
  font-family: var(--serif);
  font-size: 54px;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.hud-bl { position: absolute; left: 32px; bottom: 30px; }
.hud-br { position: absolute; right: 32px; bottom: 30px; }
.meter { display: flex; flex-direction: column; gap: 8px; width: 220px; }
.meter.right { align-items: flex-end; }
.meter .micro b { color: var(--ivory); font-weight: 500; font-variant-numeric: tabular-nums; }
.bar { position: relative; width: 100%; height: 2px; background: rgba(156, 185, 201, 0.25); }
.bar i {
  position: absolute; left: 0; top: -1px; height: 4px; width: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: var(--aurora);
  box-shadow: 0 0 10px rgba(47, 143, 163, 0.7);
  transition: background 0.2s;
}
.bar.speed i { background: var(--ivory); box-shadow: 0 0 10px rgba(243, 233, 221, 0.5); }
.bar.speed i.boost { background: var(--gold); box-shadow: 0 0 16px rgba(255, 210, 122, 0.8); }
.bar.will i.low { background: var(--red); box-shadow: 0 0 10px rgba(217, 37, 37, 0.7); }
.anchor {
  position: absolute; left: 0; top: 0;
  width: 112px; height: 112px;
  margin: -56px 0 0 -56px;
  display: flex; align-items: center; justify-content: center;
  will-change: transform;
}
/* The dial is a fixed scale, not a fill meter: the same degrees on every
   corner of every sigil, so the player learns one gesture. pathLength=360
   makes dash units degrees, so every band is a static declaration. */
.anchor svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.anchor .dial { transform: rotate(-90deg); filter: drop-shadow(0 0 3px rgba(6, 18, 31, 0.95)); }
.anchor circle { fill: none; stroke-linecap: butt; }
.anchor .track { stroke: rgba(156, 185, 201, 0.3); stroke-width: 1; }
.anchor .blown { stroke: var(--ember); stroke-width: 1.5; opacity: 0.45; }
.anchor .good { stroke: var(--aurora); stroke-width: 2.5; opacity: 0.75; }
.anchor .perfect {
  stroke: var(--gold); stroke-width: 5;
  transition: stroke-width 0.06s linear;
  filter: drop-shadow(0 0 5px rgba(255, 210, 122, 0.7));
}
.anchor .ghost { stroke: var(--gold); stroke-width: 5; opacity: 0; }
.anchor.in-perfect .perfect { stroke-width: 7; }
.anchor.fired .ghost { animation: ghostring 0.3s ease-out both; }
@keyframes ghostring {
  from { opacity: 0.85; transform: scale(1); }
  to { opacity: 0; transform: scale(1.34); }
}
.anchor .ghost { transform-origin: 50% 50%; }
.anchor .needle-layer line {
  stroke: var(--ivory); stroke-width: 2.4; stroke-linecap: round;
  transform-box: view-box; transform-origin: 50px 50px;
  filter: drop-shadow(0 0 4px rgba(6, 18, 31, 0.95));
}
.anchor.blown .needle-layer line { stroke: var(--ember); stroke-width: 3.2; }
.anchor.blown .perfect { opacity: 0.35; }
.anchor.rolled .track, .anchor.rolled .blown { opacity: 0.12; }
.anchor span {
  font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ivory);
  text-shadow: 0 0 10px rgba(6, 18, 31, 0.9);
}
.anchor.tethered .track { stroke: rgba(255, 210, 122, 0.4); }
.anchor.in-perfect span { color: var(--gold); }
.anchor.blown span { color: var(--ember); }

/* a rule down the screen edge you are being thrown toward */
.edge {
  position: absolute; top: 0; bottom: 0; width: 3px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.12s ease-out;
}
.edge.left { left: 0; }
.edge.right { right: 0; }
.edge.on { opacity: 0.9; transition: opacity 0.05s linear; }
.edge.ember { background: linear-gradient(to bottom, rgba(255, 90, 54, 0), var(--ember), rgba(255, 90, 54, 0)); }
.edge.red { background: linear-gradient(to bottom, rgba(217, 37, 37, 0), var(--red), rgba(217, 37, 37, 0)); }
.bar i.hit { background: var(--red) !important; box-shadow: 0 0 14px rgba(217, 37, 37, 0.9) !important; }
.toast {
  position: absolute; left: 50%; top: 30%;
  transform: translate(-50%, 10px) scale(0.96);
  font-family: var(--serif);
  font-size: 46px; letter-spacing: -0.02em; line-height: 1;
  color: var(--ivory);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
  text-shadow: 0 0 24px rgba(6, 18, 31, 0.9);
  white-space: nowrap;
}
.toast.on { opacity: 1; transform: translate(-50%, 0) scale(1); }
.toast.gold { color: var(--gold); text-shadow: 0 0 28px rgba(255, 210, 122, 0.6); }
.toast.ember { color: var(--ember); }
.toast.red { color: var(--red); }
.hint {
  position: absolute; left: 50%; bottom: 96px;
  transform: translateX(-50%);
  opacity: 0; transition: opacity 0.4s;
  color: var(--ivory);
}
.hint.on { opacity: 0.9; }
.countdown {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.countdown span {
  font-family: var(--serif);
  font-size: clamp(120px, 22vh, 220px);
  line-height: 1; letter-spacing: -0.04em;
  color: var(--ivory);
  text-shadow: 0 0 40px rgba(255, 210, 122, 0.35);
}
.countdown span.pop { animation: pop 0.55s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes pop {
  from { opacity: 0; transform: scale(1.7); filter: blur(6px); }
  to { opacity: 1; transform: scale(1); filter: blur(0); }
}

/* -------------------------------------------------------------- results */
.results {
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at 50% 50%, rgba(6, 18, 31, 0.55), rgba(6, 18, 31, 0.2) 60%, rgba(6, 18, 31, 0.6));
}
.results-block {
  width: min(460px, 92vw);
  max-height: 92vh;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 14px;
  padding: 26px 30px 28px;
  background: rgba(6, 18, 31, 0.58);
  border-top: 2px solid var(--red);
}
@media (min-width: 1100px) {
  .results { justify-content: flex-end; padding-right: 6vw; }
}
.grade {
  font-family: var(--serif);
  font-size: 96px; line-height: 0.9; letter-spacing: -0.05em;
  color: var(--gold);
}
.grade[data-grade="B"] { color: var(--ivory); }
.grade[data-grade="C"] { color: var(--mist); }
.rows { display: flex; flex-direction: column; }
.rows div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
  padding: 7px 0;
  border-top: 1px solid var(--mystic);
}
.rows strong { font-family: var(--serif); font-size: 19px; letter-spacing: -0.02em; text-align: right; font-variant-numeric: tabular-nums; }
.results-intention { margin: 2px 0 0; font-size: 16px; line-height: 1.3; color: var(--ivory); }
.actions { display: flex; gap: 14px; flex-wrap: wrap; }
.actions button {
  border: 0; background: transparent;
  padding: 8px 0;
  font-family: var(--serif); font-size: 22px; letter-spacing: -0.02em;
  color: var(--ivory);
  border-bottom: 2px solid var(--red);
  transition: color 0.2s, border-color 0.2s;
}
.actions button:hover { color: var(--gold); border-color: var(--gold); }
.actions kbd { margin-left: 8px; font-family: var(--sans); font-size: 11px; letter-spacing: 0.16em; color: var(--mist); }

.debug {
  position: fixed; left: 12px; bottom: 90px; z-index: 9;
  margin: 0; padding: 8px 10px;
  font: 11px/1.4 ui-monospace, Menlo, monospace;
  color: var(--mist);
  background: rgba(6, 18, 31, 0.6);
  pointer-events: none;
  white-space: pre;
}

/* ---------------------------------------------------------- responsive */
/* HUD scales with the viewport rather than stepping at one breakpoint, so a
   phone, a tablet and a 4K monitor all read the same way. */
.hud-tl { left: clamp(14px, 2.5vw, 32px); top: clamp(12px, 2.2vh, 28px); }
.hud-tr { right: clamp(14px, 2.5vw, 32px); top: clamp(10px, 2vh, 22px); }
.hud-bl { left: clamp(14px, 2.5vw, 32px); bottom: clamp(14px, 3vh, 30px); }
.hud-br { right: clamp(14px, 2.5vw, 32px); bottom: clamp(14px, 3vh, 30px); }
.letters { font-size: clamp(17px, 2.6vw, 26px); }
.time { font-size: clamp(30px, 5.2vw, 54px); }
.meter { width: clamp(96px, 18vw, 220px); }
.toast { font-size: clamp(24px, 5.4vw, 46px); }
.countdown span { font-size: clamp(90px, 20vh, 220px); }
.anchor { width: clamp(84px, 13vw, 112px); height: clamp(84px, 13vw, 112px); }
.anchor { margin: calc(clamp(84px, 13vw, 112px) / -2) 0 0 calc(clamp(84px, 13vw, 112px) / -2); }
.anchor span { font-size: clamp(10px, 1.4vw, 12px); }
.grade { font-size: clamp(64px, 12vw, 96px); }

@media (max-width: 860px) {
  .panel {
    width: 100%;
    background: linear-gradient(180deg, rgba(6, 18, 31, 0.9) 0%, rgba(6, 18, 31, 0.78) 55%, rgba(6, 18, 31, 0.93) 100%);
  }
  .hud-tl { max-width: 58vw; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: 10px 16px; }
  .result { flex-direction: column; align-items: flex-start; gap: 6px; }
  .reduced { font-size: clamp(22px, 6vw, 30px); }
  .results-block { padding: 22px 22px 24px; gap: 12px; }
  .rows strong { font-size: 17px; }
  .actions { gap: 10px; }
  .actions button { font-size: 19px; }
  .actions kbd { display: none; }
}

/* landscape phones: very little vertical room, so drop the decorative lines */
@media (max-height: 520px) {
  .panel { gap: 10px; padding-top: 14px; }
  .panel h1 { font-size: clamp(26px, 7vh, 40px); }
  .ops { display: none; }
  .letter-stream { max-height: 16vh; }
  .stats { padding-top: 8px; }
  .legend { display: none; }
  .seal { padding: 11px 22px 12px; font-size: 20px; }
  .hud-tl .intention-line { display: none; }
}

/* Touch devices get no hover, no keyboard, and the thumb zones must stay clear.
   The keyboard legend is meaningless on a phone, so swap it for the touch one. */
.legend-touch { display: none; }
@media (hover: none), (pointer: coarse) {
  .legend-keys { display: none; }
  .legend-touch { display: flex; }
  .seal:hover:not(:disabled) { transform: none; }
  .hint { bottom: clamp(60px, 14vh, 96px); }
}

/* ------------------------------------------------------------ dev panel */
#dev {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  z-index: 20;
  width: min(330px, 92vw);
  overflow-y: auto;
  padding: 14px 16px 28px;
  background: rgba(6, 18, 31, 0.93);
  border-left: 1px solid var(--mystic);
  font: 11px/1.5 var(--sans);
  color: var(--mist);
  backdrop-filter: blur(6px);
}
.dev-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.dev-head strong { color: var(--ivory); font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; }
.dev-hint { opacity: 0.6; }
#dev .dev-row { display: flex; flex-direction: column; gap: 2px; margin: 7px 0; }
#dev label { display: flex; justify-content: space-between; gap: 8px; letter-spacing: 0.04em; }
#dev output { color: var(--gold); font-variant-numeric: tabular-nums; }
#dev input[type="range"] { width: 100%; accent-color: var(--red); height: 16px; }
.dev-scrub { padding: 8px 0 10px; border-bottom: 1px solid var(--mystic); }
.dev-scrub label { color: var(--ivory); }
.dev-scrub input[type="range"] { accent-color: var(--gold); height: 22px; }
.dev-buttons { flex-direction: row !important; flex-wrap: wrap; gap: 6px; padding: 8px 0; }
#dev button {
  flex: 1 1 auto; padding: 6px 8px;
  background: transparent; color: var(--ivory);
  border: 1px solid var(--mystic);
  font: inherit; letter-spacing: 0.08em; text-transform: uppercase;
}
#dev button:hover { border-color: var(--gold); color: var(--gold); }
.dev-readout {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px 10px;
  padding: 8px 0; margin-bottom: 6px;
  border-top: 1px solid var(--mystic); border-bottom: 1px solid var(--mystic);
  font-variant-numeric: tabular-nums;
}
.dev-readout span:last-child { grid-column: 1 / -1; }
.dev-readout b { color: var(--ivory); font-weight: 500; }
#dev details { border-top: 1px solid rgba(22, 62, 104, 0.6); padding: 4px 0; }
#dev summary { cursor: pointer; padding: 5px 0; color: var(--ivory); letter-spacing: 0.1em; text-transform: uppercase; }

/* -------------------------------------------------------------- landing */
/* Ships visible: `.landing` carries `on` from the markup so it paints with no
   JavaScript at all. Everything here must hold up before a single module has
   loaded. It is also the one screen that scrolls. */
.landing {
  display: block;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  background:
    radial-gradient(60vw 60vw at 78% 18%, rgba(47, 143, 163, 0.16), rgba(6, 18, 31, 0) 62%),
    radial-gradient(52vw 52vw at 12% 52%, rgba(22, 62, 104, 0.3), rgba(6, 18, 31, 0) 66%),
    var(--abyss);
}
.landing-scroll {
  width: min(1180px, 100%);
  margin: 0 auto;
  padding: 0 clamp(22px, 5vw, 64px) clamp(40px, 8vh, 90px);
}

/* The hero is edge to edge, outside the 1180px column, with the lap running
   behind it. The copy sits low, the way a film title does. */
.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: flex-end;
  padding: clamp(80px, 12vh, 140px) clamp(22px, 5vw, 64px) clamp(56px, 10vh, 110px);
  overflow: hidden;
}
.hero-media { position: absolute; inset: 0; background: var(--abyss); }
.hero-video,
.hero-media::after {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Readable type over moving picture, without a full-screen linear wash: a pool
   of ground under the copy and a flat settle over the rest. */
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(135% 105% at 16% 92%, rgba(6, 18, 31, 0.96) 0%, rgba(6, 18, 31, 0.72) 38%, rgba(6, 18, 31, 0.18) 78%),
    radial-gradient(90% 60% at 50% 104%, rgba(6, 18, 31, 0.92), rgba(6, 18, 31, 0) 70%),
    rgba(6, 18, 31, 0.28);
}
.hero-inner {
  position: relative;
  width: min(1180px, 100%);
  margin: 0 auto;
  max-width: 100%;
}
.landing-copy { max-width: 34em; }
.landing h1 {
  margin: 14px 0 0;
  max-width: 15em;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(38px, 7.2vw, 104px);
  line-height: 0.92;
  letter-spacing: -0.04em;
  text-shadow: 0 2px 40px rgba(6, 18, 31, 0.7);
}
.landing h1 em { font-style: normal; color: var(--gold); }
.lede {
  margin: clamp(16px, 2.6vh, 26px) 0 0;
  padding-left: 14px;
  border-left: 4px solid var(--red);
  font-size: clamp(17px, 2.2vh, 20px);
  line-height: 1.5;
  color: var(--ivory);
  max-width: 30em;
}
.beats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin: clamp(18px, 3vh, 30px) 0 0;
  padding: 10px 0;
  list-style: none;
  border-top: 1px solid var(--mystic);
  border-bottom: 1px solid var(--mystic);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mist);
}
.beats li + li::before {
  content: "";
  display: inline-block;
  width: 26px;
  height: 1px;
  margin-right: 14px;
  vertical-align: middle;
  background: var(--aurora);
}
.landing .seal { margin-top: clamp(20px, 3.4vh, 34px); }
.landing-note {
  margin: 14px 0 0;
  /* a sentence, not a label: the micro class would shout it */
  font-size: 13px;
  letter-spacing: 0.01em;
  text-transform: none;
  line-height: 1.5;
  max-width: 34em;
}
.landing-note b { color: var(--gold); font-weight: inherit; }
.scroll-cue {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: clamp(14px, 2.6vh, 26px);
  opacity: 0.55;
  text-align: center;
}
.scroll-cue::after {
  content: "";
  display: block;
  width: 1px;
  height: 22px;
  margin: 8px auto 0;
  background: linear-gradient(var(--aurora), transparent);
}

.lw circle { fill: none; stroke: rgba(47, 143, 163, 0.22); stroke-width: 2; }
.ls {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke-dashoffset 3.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.ls-bed  { stroke: #160e12; stroke-width: 58; }
.ls-scar { stroke: var(--char); stroke-width: 42; transition-delay: 0.12s; }
.ls-red  { stroke: var(--red); stroke-width: 19; filter: drop-shadow(0 0 16px rgba(217, 37, 37, 0.7)); transition-delay: 0.26s; }
.ls-hot  { stroke: var(--gold); stroke-width: 6; filter: drop-shadow(0 0 10px var(--ember)); transition-delay: 0.4s; }
.ls-end {
  stroke: var(--gold);
  stroke-width: 6;
  fill: none;
  opacity: 0;
  transition: opacity 0.6s ease 3.2s;
}

/* --- the sections below the fold --- */
.lsec {
  padding: clamp(34px, 7vh, 78px) 0;
  border-top: 1px solid var(--mystic);
}
.lsec > .micro { margin-bottom: clamp(18px, 3vh, 30px); }
.cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 4vw, 52px);
}
.cols h3, .lrows dt {
  margin: 0 0 8px;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(21px, 2.9vh, 27px);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--ivory);
}
.cols p, .lrows dd {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--mist);
  max-width: 34em;
}
.lrows { margin: 0; }
.lrows > div {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
  gap: 6px clamp(18px, 4vw, 48px);
  padding: clamp(14px, 2.4vh, 20px) 0;
  border-top: 1px solid rgba(22, 62, 104, 0.6);
}
.lrows > div:first-child { border-top: 0; padding-top: 0; }
.lrows dd { margin: 0; }

.lsec-free .big {
  margin: 0 0 18px;
  max-width: 22em;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(24px, 4vh, 40px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--gold);
}
.lsec-free p { max-width: 38em; font-size: 16px; line-height: 1.55; color: var(--ivory); }
.lfoot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px 20px;
  padding-top: clamp(20px, 4vh, 38px);
  border-top: 1px solid var(--mystic);
}

@media (max-width: 900px) {
  .landing h1 { font-size: clamp(32px, 9.5vw, 58px); }
  .landing-copy { max-width: none; }
  .cols { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .lrows > div { grid-template-columns: minmax(0, 1fr); }
}
@media (max-height: 560px) {
  .landing h1 { font-size: clamp(28px, 7vw, 44px); }
  .hero { min-height: 100dvh; padding-bottom: 36px; }
  .scroll-cue { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ls, .ls-end { transition: none; }
}

/* ------------------------------------------------------------------ nav */
.nav {
  position: fixed;
  top: clamp(12px, 2.2vh, 22px);
  left: clamp(16px, 3vw, 40px);
  right: clamp(16px, 3vw, 40px);
  z-index: 8;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  pointer-events: none;
}
.nav > * { pointer-events: auto; position: relative; z-index: 1; }
.nav-links { display: flex; gap: 18px; }
/* the wordmark is the way home from every screen */
.nav-mark {
  font-family: var(--serif);
  font-size: clamp(17px, 2.2vh, 23px);
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--ivory);
}
.nav-mark:hover { color: var(--gold); }
.nav a.on { color: var(--gold); border-color: var(--gold); }
.nav a {
  color: var(--mist);
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}
.nav a:hover { color: var(--gold); border-color: var(--gold); }
/* A run gets the whole screen. :has() keeps this a fact about the HUD rather
   than another thing the game has to remember to toggle. */
body:has(#hud:not([hidden])) .nav { display: none; }
/* The landing scrolls under the fixed nav, so the nav needs a little ground of
   its own or the copy runs through it. */
body:has(#landing:not([hidden])) .nav::before {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: clamp(74px, 12vh, 118px);
  /* zero, not -1: a negative z-index here drops the scrim behind the landing
     rather than behind the nav's own links, which is the whole job. */
  z-index: 0;
  background: linear-gradient(rgba(6, 18, 31, 0.92), rgba(6, 18, 31, 0.62) 45%, rgba(6, 18, 31, 0));
  pointer-events: none;
}
/* four links do not fit across a phone at 0.18em tracking */
@media (max-width: 660px) {
  .nav {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  .nav-links { gap: 13px; }
  .nav-mark { font-size: 13px; }
  /* the nav wraps to two lines here, so the sheets need more headroom */
  .sheet .panel { padding-top: 84px; }
}

/* ------------------------------------------------------- sheet screens */
/* Full-bleed panels (settings, and the library and journey map to come). The
   intention screen's panel is a left-hand column over the live world; these sit
   over a dimmed ground and centre themselves. */
.sheet {
  display: flex;
  justify-content: center;
  background: rgba(6, 18, 31, 0.86);
  overflow-y: auto;
}
.sheet .panel {
  width: min(620px, 100%);
  background: none;
  /* clear the fixed nav, which sits above these screens */
  padding-top: clamp(56px, 8vh, 84px);
}
/* Screens carrying a diagram need room to be a diagram. Same width token the
   landing page uses. */
.sheet-wide .panel { width: min(1180px, 100%); }
.sheet h1 {
  margin: 6px 0 clamp(18px, 3vh, 30px);
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(34px, 5vh, 56px);
  line-height: 0.95;
  letter-spacing: -0.035em;
}
.block {
  padding: clamp(16px, 2.6vh, 24px) 0;
  border-top: 1px solid var(--mystic);
}
.block .micro { margin-bottom: 10px; }
.note {
  margin: 0 0 14px;
  max-width: 46em;
  font-size: 14px;
  line-height: 1.5;
  color: var(--mist);
}
.note.ok { color: var(--gold); }
.note.bad { color: var(--ember); }
.sheet .lede { margin: 0 0 16px; font-size: clamp(16px, 2vh, 18px); }
.sheet .stats { border-top: 0; padding-top: 0; }

/* a secondary action: an underlined word, never a boxed button */
button.line {
  border: 0;
  background: transparent;
  padding: 8px 0;
  font-family: var(--serif);
  font-size: 20px;
  letter-spacing: -0.02em;
  color: var(--ivory);
  border-bottom: 2px solid var(--red);
  transition: color 0.2s, border-color 0.2s;
}
button.line:hover { color: var(--gold); border-color: var(--gold); }
button.danger-line { border-color: var(--char); color: var(--mist); }
button.danger-line:hover,
button.danger-line.armed { color: var(--ember); border-color: var(--ember); }

.choice {
  display: flex;
  gap: 22px;
  margin-bottom: 16px;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mist);
}
.choice label { display: flex; align-items: center; gap: 7px; cursor: pointer; }
.sheet .panel-foot { align-items: flex-start; }
.sheet .panel-foot button.line { align-self: flex-start; }
.choice input { accent-color: var(--red); }

/* --------------------------------------------------------- wheel picker */
.picker {
  padding-top: clamp(12px, 2vh, 20px);
}
.picker-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 8px 0 8px;
  border-top: 1px solid var(--mystic);
  border-bottom: 1px solid var(--mystic);
}
button.pick {
  flex: 1 1 auto;
  border: 0;
  background: transparent;
  padding: 9px 10px;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mist);
  border-bottom: 2px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}
button.pick + button.pick { border-left: 1px solid var(--mystic); }
button.pick:hover { color: var(--ivory); }
button.pick.on { color: var(--gold); border-bottom-color: var(--red); }
.picker-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--mist);
  opacity: 0.85;
}
/* Flexbox already honours `direction`, so `dir="rtl"` on the container is the
   whole fix — adding row-reverse on top double-reverses it and breaks wrapping
   onto the second line. */
[lang="he"] { font-family: var(--hebrew); }
.sl { min-width: 15px; width: auto; }

/* ---------------------------------------------------------- journey map */
.maps {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  gap: clamp(14px, 3vw, 34px);
  padding: clamp(14px, 2.4vh, 22px) 0;
  border-top: 1px solid var(--mystic);
}
.map { margin: 0; min-width: 0; }
.map figcaption { margin-bottom: 8px; }
.map svg { width: 100%; height: auto; overflow: visible; }

.jskel {
  fill: none;
  stroke: var(--mystic);
  stroke-width: 0.5;
}
.jn { cursor: pointer; outline: none; }
.jn-halo {
  fill: none;
  stroke: var(--mystic);
  stroke-width: 0.8;
  transition: stroke 0.25s, stroke-width 0.25s;
}
.jn-core {
  /* Solid in every state. Locked is a muted fill, applied from JS, because
     alpha was being used to mean "not yet" and it read as "not there". */
  transition: fill 0.25s;
}
.jn-label {
  font-family: var(--sans);
  font-size: 3.4px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  fill: var(--mist);
  transition: fill 0.25s;
}
.jn-charge {
  font-family: var(--serif);
  font-size: 5.4px;
  fill: var(--abyss);
  opacity: 0;
  transition: opacity 0.25s;
}
/* cleared: the sphere burns in its own colour and shows how many times it has
   been charged. The count only ever goes up, so it is a score, not a tally of
   failures. */
.jn.cleared .jn-halo { stroke: var(--gold); stroke-width: 1.3; }
.jn.cleared .jn-label { fill: var(--ivory); }
.jn-label { fill: var(--mist); }
.jn.cleared .jn-charge { opacity: 0.75; }
.jn.locked { cursor: not-allowed; }
.jn.locked .jn-halo { stroke: #24405c; }
.jn.locked .jn-label { fill: #4d6376; }
.jn.on .jn-halo { stroke: var(--red); stroke-width: 1.8; }
.jn:hover:not(.locked) .jn-halo { stroke: var(--ivory); }
.jn:focus-visible .jn-halo { stroke: var(--gold); stroke-width: 1.6; }

.stage {
  padding-top: clamp(14px, 2.4vh, 22px);
  border-top: 1px solid var(--mystic);
}
.stage-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
}
.stage-head h2 {
  margin: 4px 0 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(26px, 3.6vh, 38px);
  line-height: 1;
  letter-spacing: -0.03em;
}
.stage-heb {
  font-family: var(--hebrew);
  font-size: clamp(30px, 4.4vh, 46px);
  line-height: 1;
  color: var(--gold);
}
.stage .field { display: block; margin-top: 14px; }
.stage .field .micro {
  display: block;
  margin-bottom: 8px;
  letter-spacing: 0.06em;
  text-transform: none;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ivory);
}
.stage textarea:disabled { opacity: 0.4; cursor: not-allowed; }
.jfoot { display: flex; align-items: center; gap: 20px; }
.jfoot .seal { flex: 1 1 auto; }

@media (max-width: 720px) {
  .maps { grid-template-columns: minmax(0, 1fr); }
  .jn-label { font-size: 3px; }
  .jfoot { flex-direction: column; align-items: stretch; }
}

/* ------------------------------------------------------------- library */
.lib { padding-top: 4px; }
.lib-row {
  padding: clamp(14px, 2.4vh, 20px) 0;
  border-top: 1px solid var(--mystic);
}
.lib-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
}
.lib-text {
  margin: 0;
  flex: 1 1 auto;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ivory);
}
.lib-chars {
  flex: 0 0 auto;
  max-width: 45%;
  font-family: var(--serif);
  font-size: 15px;
  letter-spacing: 0.08em;
  color: var(--gold);
  text-align: right;
}
.lib-chars[lang="he"] { font-family: var(--hebrew); }
.lib-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
}
.lib-meta span + span::before {
  content: "·";
  margin-right: 14px;
  color: var(--mystic);
}
.lib-actions { display: flex; gap: 22px; margin-top: 8px; }
.lib-actions button.line { font-size: 17px; }

@media (max-width: 620px) {
  .lib-head { flex-direction: column; gap: 6px; }
  .lib-chars { max-width: none; text-align: left; }
  .lib-chars[dir="rtl"] { text-align: right; }
}

/* --------------------------------------------------------- today's angel */
.angel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
}
.angel-head h1 { margin: 4px 0 0; }
.angel-title {
  margin: 6px 0 0;
  font-family: var(--serif);
  font-size: clamp(17px, 2.3vh, 21px);
  letter-spacing: -0.01em;
  color: var(--gold);
}
.angel-heb {
  flex: 0 0 auto;
  font-family: var(--hebrew);
  font-size: clamp(34px, 5.4vh, 60px);
  line-height: 1.1;
  color: var(--gold);
  white-space: nowrap;
}
/* A long transliteration next to five Hebrew letters does not fit a phone
   column; stack them rather than squeezing the name. */
@media (max-width: 560px) {
  .angel-head { flex-direction: column-reverse; align-items: flex-start; gap: 6px; }
  .stage-head { flex-direction: column-reverse; align-items: flex-start; gap: 4px; }
}
/* how far the Sun has crossed this angel's arc */
.arcbar {
  height: 3px;
  background: var(--mystic);
  overflow: hidden;
}
.arcbar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--red), var(--gold));
  transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
#daily .field { display: block; margin-top: 18px; }
#daily .field .micro {
  display: block;
  margin-bottom: 8px;
  letter-spacing: 0.06em;
  text-transform: none;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ivory);
}

/* the mark band: the sigil drawing itself, below the fold */
.lsec-mark .mark-band {
  display: flex;
  justify-content: center;
  padding: clamp(8px, 2vh, 20px) 0;
}
.mark-band #landingSigil {
  width: 100%;
  max-width: min(64vh, 560px);
  height: auto;
  overflow: visible;
}
.mark-note {
  margin: clamp(10px, 2vh, 18px) 0 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--mist);
  text-align: center;
}
.mark-note q { color: var(--ivory); font-style: normal; }

/* ---------------------------------------------------------- campaigns */
.campaigns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 44px);
  padding: clamp(14px, 2.4vh, 24px) 0;
  border-top: 1px solid var(--mystic);
}
.campaign {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  padding-top: 4px;
}
.campaign h2 {
  margin: 4px 0 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(22px, 3.2vh, 32px);
  line-height: 1;
  letter-spacing: -0.03em;
}
.campaign .note { margin: 0; }
.campaign .cmap { display: flex; justify-content: center; padding: 4px 0 2px; }
.campaign svg { width: 100%; max-width: 340px; height: auto; overflow: visible; }
/* how much of the campaign is charged */
.cbar { height: 3px; background: var(--mystic); overflow: hidden; }
.cbar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--red), var(--gold));
  transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.cstate { margin: 0; }
.campaign .cgo { align-self: flex-start; font-size: 19px; }
.campaign.locked { opacity: 0.72; }
.campaign.locked h2 { color: var(--mist); }
button.cgo:disabled { color: var(--mist); border-color: var(--char); cursor: not-allowed; }

@media (max-width: 860px) {
  .campaigns { grid-template-columns: minmax(0, 1fr); gap: 30px; }
}

/* today's angel, given room to be two things at once */
.angel-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(20px, 4vw, 52px);
  align-items: start;
}
.angel-main, .angel-side { display: flex; flex-direction: column; gap: clamp(12px, 2.2vh, 22px); min-width: 0; }
.angel-side .block:first-child { border-top: 0; padding-top: 0; }
@media (max-width: 860px) {
  .angel-grid { grid-template-columns: minmax(0, 1fr); gap: 18px; }
}

/* the line under the grade: where you were, and whether it counted */
.results-note {
  margin: -4px 0 4px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--mist);
  max-width: 30em;
}
#nextButton { color: var(--gold); border-bottom-color: var(--gold); }
#nextButton:hover { color: var(--ivory); border-color: var(--ivory); }

/* The opening section under the hero: the lede and the three beats, which used
   to sit beside the title and now follow it. */
.lsec-open { border-top: 0; padding-top: clamp(30px, 6vh, 64px); }
.lsec-open .lede { font-size: clamp(18px, 2.4vh, 23px); max-width: 26em; }

/* Sections arrive as you reach them. The class is added by JS, so with no
   JavaScript at all every section is simply visible. */
.landing-scroll.reveal .lsec,
.landing-scroll.reveal .lfoot {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.landing-scroll.reveal .lsec.in,
.landing-scroll.reveal .lfoot.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .landing-scroll.reveal .lsec,
  .landing-scroll.reveal .lfoot { opacity: 1; transform: none; transition: none; }
}

/* ----------------------------------------------------------- copy editing */
/* Edit mode turns every keyed line into a field in place. The outline is the
   whole affordance: there is no separate editor pane, because the point is to
   see the writing in its own typography while you change it. */
.ce-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
  background: rgba(6, 18, 31, 0.92);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--mystic);
}
.ce-left { display: flex; align-items: baseline; gap: 10px; }
.ce-left strong { color: var(--gold); letter-spacing: 0.18em; }
.ce-count { color: var(--mist); }
.ce-right { display: flex; gap: 8px; flex-wrap: wrap; }
.ce-right button { font-size: 12px; padding: 7px 12px; }

body.editing-copy .ce-on {
  outline: 1px dashed rgba(156, 185, 201, 0.5);
  outline-offset: 3px;
  border-radius: 2px;
  cursor: text;
}
body.editing-copy .ce-on:hover { outline-color: var(--aurora); }
body.editing-copy .ce-on:focus {
  outline: 1px solid var(--gold);
  background: rgba(255, 210, 122, 0.08);
}
/* The bar sits over the foot of every sheet, so give them room to clear it. */
body.editing-copy .panel-foot,
body.editing-copy .lfoot { margin-bottom: 68px; }
.ce-go { display: flex; gap: 6px; flex-wrap: wrap; }
.ce-go button { font-size: 11px; padding: 6px 10px; }
.ce-go button.on { color: var(--gold); border-color: var(--gold); }
