/* Sigmund Void — someone's notebook that kept going past the edge of the
   page. Graph paper, ink, red thread pinned between objects that are
   related for reasons the page will not explain. Night mode is a blueprint
   of the same thought. The sign-in is a small sign on a nail: legible,
   but just one more object in the room. */

:root {
  --paper: #e2ebe7;
  --grid: rgba(30, 60, 210, 0.12);
  --grid-strong: rgba(30, 60, 210, 0.25);
  --ink: #16143a;
  --ink-soft: rgba(22, 20, 58, 0.62);
  --thread: #e3261c;
  --glow: #5a2bff;
  --blue: #1f3cff;
  --hl: #dcff2e;
  --serif: "EB Garamond", ui-serif, Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  --hand: "Reenie Beanie", "Bradley Hand", cursive;
  --frak: "UnifrakturMaguntia", "Old English Text MT", serif;
  /* colored pencils, nearest to hand */
  --p1: #e3261c;
  --p2: #1f3cff;
  --p3: #ffc800;
  --p4: #00995a;
  --p5: #8a2be2;
  --p6: #ff6a00;
  --band: 30px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0a0f2e;
    --grid: rgba(120, 170, 255, 0.1);
    --grid-strong: rgba(120, 170, 255, 0.22);
    --ink: #eef1ff;
    --ink-soft: rgba(238, 241, 255, 0.62);
    --thread: #ff4436;
    --glow: #c9ff2e;
    --blue: #59a8ff;
    --hl: rgba(201, 255, 46, 0.35);
    --p1: #ff4d3d;
    --p2: #4d9bff;
    --p3: #ffe14d;
    --p4: #2ee59d;
    --p5: #c58cff;
    --p6: #ff9a3d;
  }
}

:root[data-theme="dark"] {
  --paper: #0a0f2e;
  --grid: rgba(120, 170, 255, 0.1);
  --grid-strong: rgba(120, 170, 255, 0.22);
  --ink: #eef1ff;
  --ink-soft: rgba(238, 241, 255, 0.62);
  --thread: #ff4436;
  --glow: #c9ff2e;
  --blue: #59a8ff;
  --hl: rgba(201, 255, 46, 0.35);
  --p1: #ff4d3d;
  --p2: #4d9bff;
  --p3: #ffe14d;
  --p4: #2ee59d;
  --p5: #c58cff;
  --p6: #ff9a3d;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  overflow: hidden;
}

body {
  height: 100dvh;
  color: var(--ink);
  font-family: var(--serif);
  background-color: var(--paper);
  /* graph paper: fine lines every 24px, bold every 120px */
  background-image:
    linear-gradient(var(--grid-strong) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-strong) 1px, transparent 1px),
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size:
    120px 120px,
    120px 120px,
    24px 24px,
    24px 24px;
  cursor: crosshair;
}

#field {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.scrawl {
  font-family: var(--hand);
  font-size: 1.25em;
  color: var(--ink-soft);
}

/* ── title ─────────────────────────────────────────── */

.brand {
  position: fixed;
  top: clamp(28px, 7vh, 64px);
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
  z-index: 3;
}

.brand h1 {
  margin: 0;
  font-weight: 500;
  font-size: clamp(34px, 8vw, 84px);
  letter-spacing: 0.18em;
  line-height: 1;
}

.brand h1 .l {
  display: inline-block;
  transition: transform 0.6s ease;
}

/* letters the page has decided to circle */
.brand h1 .l.circled {
  outline: 1.5px solid var(--thread);
  outline-offset: 2px;
  border-radius: 50%;
}

.brand h1 .l.glitch {
  color: var(--glow);
}

.sub {
  margin: 10px 0 0;
}

.null {
  font-size: clamp(22px, 4vw, 34px);
  color: var(--glow);
  margin-right: 6px;
  display: inline-block;
  animation: spin 31s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── objects ───────────────────────────────────────── */

.obj {
  position: fixed;
  z-index: 2;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: 2px;
  color: var(--ink);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.obj .shape {
  width: clamp(40px, 6vw, 68px);
  height: clamp(40px, 6vw, 68px);
  display: grid;
  place-items: center;
  font-size: clamp(32px, 5vw, 54px);
  line-height: 1;
  transition: transform 0.4s ease, color 0.3s ease;
}

.obj svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.obj .tag {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  white-space: nowrap;
}

.obj .note {
  position: absolute;
  top: 100%;
  left: 50%;
  width: max-content;
  max-width: 190px;
  margin-top: 4px;
  font-family: var(--hand);
  font-size: 21px;
  line-height: 1;
  color: var(--thread);
  text-align: center;
  opacity: 0;
  transform: translate(-50%, -4px) rotate(-3deg);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
}

.obj:hover .shape,
.obj.lit .shape {
  color: var(--glow);
  transform: scale(1.12) rotate(-6deg);
}

.obj:hover .note,
.obj.lit .note {
  opacity: 1;
  transform: translate(-50%, 0) rotate(-3deg);
}

/* objects the hovered one is secretly connected to */
.obj.kin .shape {
  color: var(--thread);
}

/* ── scribbles spawned by clicking ─────────────────── */

.scribble {
  position: fixed;
  z-index: 2;
  font-family: var(--hand);
  font-size: 24px;
  color: var(--ink);
  white-space: nowrap;
  pointer-events: none;
  animation: scribble 7s ease forwards;
}

@keyframes scribble {
  0% {
    opacity: 0;
    filter: blur(3px);
  }
  8% {
    opacity: 1;
    filter: blur(0);
  }
  75% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateY(-14px) var(--tilt);
  }
}

/* ── the tag: an ink-outlined luggage tag on a string from a nail ── */

.sign {
  position: fixed;
  z-index: 4;
  left: 50%;
  top: 62%;
  isolation: isolate;
  transform: translateX(-50%) rotate(-2deg);
  transform-origin: 50% -22px; /* the nail */
  animation: swing 7s ease-in-out infinite alternate;
  min-width: 96px;
  padding: 22px 20px 10px;
  text-align: center;
  cursor: auto;
}

/* the tag's outline, paper-filled so the thread passes behind it */
.tag-shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  overflow: visible;
}

.tag-shape path {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 1.3;
  vector-effect: non-scaling-stroke;
}

.tag-hole {
  position: absolute;
  left: 50%;
  top: 7px;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  border: 1.2px solid var(--ink);
}

/* the string, nail to hole */
.sign::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -22px;
  width: 1px;
  height: 32px;
  margin-left: -0.5px;
  background: var(--ink-soft);
}

/* the nail is a real element so the canvas threads can find its exact center */
.nail {
  position: absolute;
  left: 50%;
  top: -25px;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--ink);
}

@keyframes swing {
  from {
    transform: translateX(-50%) rotate(-3deg);
  }
  to {
    transform: translateX(-50%) rotate(1.5deg);
  }
}

/* signed out, the tag is only there if you find the nail: hover or tap it
   (or tab to the link). Finding it adds .found, which lingers a moment after
   the pointer leaves so you can get from the nail down to the word. */
.sign.veiled {
  opacity: 0.04;
  pointer-events: none;
  transition: opacity 0.7s ease;
}

.sign.veiled .nail {
  pointer-events: auto;
  box-sizing: content-box;
  border: 8px solid transparent;
  background-clip: content-box;
  top: -33px;
  margin-left: -11px;
}

.sign.veiled.found,
.sign.veiled:focus-within {
  opacity: 1;
  pointer-events: auto;
}

.sign-title {
  margin: 0;
  font-family: var(--hand);
  font-size: 30px;
  line-height: 0.9;
}

.sign-link {
  font-family: var(--hand);
  font-size: 30px;
  line-height: 0.9;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--thread);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

.sign-link:hover,
.sign-link:focus-visible {
  color: var(--thread);
  outline: none;
}

.sign-fine {
  margin: 3px 0 0;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}

/* ── doors that only exist once you're inside ── */

/* doors are links, but otherwise just more objects in the room */
.obj.secret {
  text-decoration: none;
}

.obj.secret:focus-visible {
  outline: none;
}

.obj.secret:focus-visible .shape {
  color: var(--glow);
}

.obj text {
  fill: currentColor;
  stroke: none;
  font-family: var(--mono);
  font-size: 10px;
  text-anchor: middle;
  dominant-baseline: central;
}

.obj .trace {
  stroke: var(--thread);
  stroke-width: 1.4;
}

/* ── the cipher in the left margin; it decodes when you look at it ── */

.cipher {
  position: fixed;
  z-index: 3;
  left: calc(var(--band) + 6px);
  top: 50%;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--ink-soft);
  white-space: nowrap;
  cursor: help;
}

.cipher:hover {
  color: var(--thread);
}

.footnotes {
  position: fixed;
  z-index: 3;
  left: calc(var(--band) + 26px);
  top: calc(var(--band) + 8px);
  margin: 0;
  font-family: var(--mono);
  font-size: 9.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  pointer-events: none;
}

.dictation {
  position: fixed;
  z-index: 2;
  font-family: var(--hand);
  font-size: 30px;
  color: var(--thread);
  pointer-events: none;
  animation: scribble 5s ease forwards;
}

.scribble.wax {
  animation: none;
  opacity: 0.07;
}

.obj.fort .shape {
  opacity: 0.12;
  transform: translate(-46px, 18px) scale(0.6) rotate(-40deg);
}

body.inverted {
  filter: invert(1) hue-rotate(180deg);
}

/* ── margins ───────────────────────────────────────── */

.coords {
  position: fixed;
  z-index: 3;
  left: calc(var(--band) + 26px);
  bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 8px);
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-soft);
  pointer-events: none;
}

.margin {
  position: fixed;
  z-index: 3;
  right: calc(var(--band) + 14px);
  bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 4px);
  font-family: var(--hand);
  font-size: 19px;
  color: var(--ink-soft);
  transform: rotate(-2deg);
  pointer-events: none;
}

.margin s {
  text-decoration-color: var(--thread);
}

.you {
  position: fixed;
  z-index: 5;
  left: 0;
  top: 0;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--thread);
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.you span {
  font-family: var(--hand);
  font-size: 17px;
}

@media (max-width: 640px) {
  .coords {
    display: none;
  }
  :root {
    --band: 12px;
  }
  .margin {
    left: 16px;
    right: 16px;
    text-align: center;
  }
  .brand h1 .l::after {
    font-size: 7px;
  }
  .obj .tag {
    display: none;
  }
  .sign {
    top: 57%;
  }
  .footnotes,
  .cipher {
    display: none;
  }
}

@media (hover: none) {
  .you {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .null,
  .sign,
  .voice::after {
    animation: none;
  }
  .scribble {
    animation: none;
  }
}

/* ── outsider-art marks: highlighter, edge bands, colored-pencil letters ── */

.hl {
  background: linear-gradient(transparent 52%, var(--hl) 52%, var(--hl) 90%, transparent 90%);
  padding: 0 3px;
}

.brand h1 .l.c1 {
  color: var(--thread);
}
.brand h1 .l.c2 {
  color: var(--blue);
}
.brand h1 .l.c3 {
  color: var(--glow);
}

.obj.kin .shape {
  color: var(--blue);
}

/* ── the border (canvas), the second layer of handwriting, the ledger ── */

#frame,
#pupils {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
}

.defs {
  position: absolute;
  width: 0;
  height: 0;
}

/* each letter carries its number */
.brand h1 .l {
  position: relative;
}

.brand h1 .l::after {
  content: attr(data-n);
  position: absolute;
  top: -0.32em;
  right: -0.1em;
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--p1);
}

.marg {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.marg span {
  position: absolute;
  white-space: nowrap;
  line-height: 1;
  opacity: 0.78;
}

.marg .f {
  font-family: var(--frak);
  font-size: 19px;
}

.marg .h {
  font-family: var(--hand);
  font-size: 22px;
}

.marg .m {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
}

.marg .s {
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
}

.marg .ring {
  outline: 1.3px solid currentColor;
  outline-offset: 3px;
  border-radius: 50%;
}

.marg .box {
  border: 1.2px solid currentColor;
  padding: 2px 4px;
}

.marg del {
  text-decoration-thickness: 1.5px;
}

/* the observation ledger: someone is writing down what you do */
/* pasted over the bottom border like a label */
.log {
  position: fixed;
  z-index: 3;
  left: calc(var(--band) * 2.4);
  bottom: 2px;
  height: calc(var(--band) - 4px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  margin: 0;
  padding: 0 9px;
  list-style: none;
  font-family: var(--mono);
  font-size: 9px;
  line-height: 1.3;
  color: var(--ink);
  background: var(--paper);
  border: 1.2px solid var(--ink);
  box-shadow: 2px 2px 0 var(--p1);
  transform: rotate(-0.6deg);
  pointer-events: none;
}

.log li {
  white-space: nowrap;
  animation: inked 1.2s ease;
}

.log li b {
  font-weight: 400;
  color: var(--p1);
}

.log li:nth-last-child(n + 2) {
  opacity: 0.5;
}

.log li:nth-last-child(n + 3) {
  display: none;
}

.redact {
  background: var(--ink);
  color: transparent;
  border-radius: 1px;
}

@keyframes inked {
  from {
    opacity: 0;
    filter: blur(2px);
  }
}

/* the voices begin sentences and leave them for you */
.voice {
  position: fixed;
  z-index: 2;
  font-family: var(--hand);
  font-size: 27px;
  color: var(--p5);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 1.4s ease;
}

.voice b {
  font-weight: 400;
  color: var(--p1);
}

.voice::after {
  content: "—";
  animation: blink 1.1s steps(2) infinite;
}

.voice.done::after {
  content: "";
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.voice.wax {
  opacity: 0.09;
}

body.lifted .scribble.wax,
body.lifted .voice.wax {
  opacity: 0.85;
  transition: opacity 0.2s ease;
}

@media (max-width: 640px) {
  .log {
    left: 50%;
    bottom: calc(env(safe-area-inset-bottom, 0px) + var(--band) + 36px);
    height: auto;
    padding: 1px 6px;
    font-size: 8.5px;
    transform: translateX(-50%) rotate(-0.6deg);
  }
  .log li:nth-last-child(n + 2) {
    display: none;
  }
  .scribble,
  .voice {
    white-space: normal;
    max-width: 62vw;
    line-height: 1;
  }
}

/* ── glow paint: invisible by day; at night it shines, then slowly gives up ── */

.glow {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  --phos: #b8ff9a;
  color: var(--phos);
  opacity: 0;
  transition: opacity 1.2s ease;
}

body.night .glow {
  opacity: 0.42;
}

body.night .glow.charged {
  animation: phosphor 75s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

@keyframes phosphor {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0.42;
  }
}

.glow-item {
  position: absolute;
  filter: drop-shadow(0 0 3px var(--phos)) drop-shadow(0 0 10px rgba(150, 255, 120, 0.55));
}

.glow-item svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.glow-item .fill {
  fill: currentColor;
  stroke: none;
}

.glow-item .ink {
  font-family: var(--hand);
  font-size: 46px;
  white-space: nowrap;
}

.glow-item .ink.small {
  font-size: 20px;
}

/* the ones in the tree blink, out of step */
.glow .pair {
  animation: lids 9s infinite;
}

@keyframes lids {
  0%, 93%, 100% {
    opacity: 1;
  }
  95% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .glow .pair,
  body.night .glow.charged {
    animation: none;
  }
}
