:root {
  color-scheme: dark;
  --paper: #000000;
  --ink: #a6a6a6;
  --space: clamp(1.5rem, 5vw, 4rem);
  --label-size: clamp(0.625rem, 1.35vw, 0.8rem);
  --label-font: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--paper);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  min-width: 0;
}

.page {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  isolation: isolate;
  min-height: 100vh;
  min-height: 100svh;
  padding:
    max(var(--space), env(safe-area-inset-top))
    max(var(--space), env(safe-area-inset-right))
    max(var(--space), env(safe-area-inset-bottom))
    max(var(--space), env(safe-area-inset-left));
}

.contact {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 1rem;
  z-index: 1;
  color: #d0d0d0;
  margin-top: 7rem;
  font-family: var(--label-font);
  font-size: var(--label-size);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  text-underline-offset: 0.3em;
  overflow-wrap: anywhere;
}

a:hover {
  text-decoration: none;
}

a:focus-visible {
  outline: 1px solid #a6a6a6;
  outline-offset: 6px;
}

.animation {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.film-grain {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.45;
}

.page.void .film-grain {
  opacity: 0;
}

.page.void :focus-visible {
  outline-color: transparent;
}

.contact-widget {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
  position: relative;
  width: max-content;
  height: 44px;
  text-align: right;
  white-space: nowrap;
}
.contact-toggle {
  position: absolute;
  right: 0;
  bottom: 0;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.contact-toggle:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 6px;
}
.contact-card {
  position: absolute;
  right: 0;
  bottom: 0;
  display: block;
  min-height: 0;
  line-height: inherit;
  visibility: hidden;
  clip-path: inset(100% 0 0 0);
}
.contact-card span { display: block; }
.contact-update { margin-top: 1.6em; }
.contact-card:hover { text-decoration: none; }
.contact-widget { width: 19ch; }
.soon {
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  position: absolute;
  top: max(var(--space), env(safe-area-inset-top));
  right: max(var(--space), env(safe-area-inset-right));
  font-family: var(--label-font);
  font-size: var(--label-size);
  line-height: 1.6;
}
.canvas-footer .soon { color: transparent; }
.soon:focus-visible { outline: 1px solid var(--ink); outline-offset: 6px; }
.canvas-footer .contact-toggle { color: transparent; }

/* Accessible DOM controls retain hit areas; Canvas paints contrast-adjusted text. */
.canvas-footer .contact a { color: transparent; }

.block-hash {
  /* Invisible DOM text supplies layout, selection and accessibility.
     Canvas keeps the visible text above the forms and adjusts its contrast. */
  opacity: 0;
  grid-column: 1;
  grid-row: 1;
  align-self: end;
  padding-bottom: calc((44px - 1.6em) / 2);
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  white-space: pre-line;
  overflow-wrap: anywhere;
  cursor: pointer;
  pointer-events: auto;
  clip-path: inset(var(--hash-time-inset, 0px) var(--hash-hover-trim, 0px) 0 0);
  user-select: text;
}

.block-hash:focus-visible {
  opacity: 1;
  color: transparent;
  background: transparent;
  outline: 1px solid var(--ink);
  outline-offset: 3px;
}

.copy-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 540px) {
  .contact { gap: 0.75rem; }
  .block-hash {
    width: 100%;
    max-width: none;
  }
}

.loop-widget {
  /* Row spacing; tightened on short screens (phones held sideways) so the menu clears the footer. */
  --loop-gap: 0.75rem;
  position: absolute;
  top: max(var(--space), env(safe-area-inset-top));
  left: max(var(--space), env(safe-area-inset-left));
  z-index: 3;
  font-family: var(--label-font);
  font-size: var(--label-size);
  line-height: 1.6;
}

.circle-count {
  display: block;
  appearance: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: default;
  font-family: var(--label-font);
  font-size: var(--label-size);
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  user-select: none;
}
.canvas-footer .circle-count { opacity: 0; }
.canvas-footer .circle-count:focus-visible {
  opacity: 1;
  color: transparent;
  outline: 1px solid var(--ink);
  outline-offset: 5px;
}

.loop-menu {
  position: absolute;
  display: block;
  top: 100%;
  left: 0;
  min-width: 10rem;
  padding: var(--loop-gap) 0;
  color: #e8e8e8;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.6rem) scaleY(0.9);
  transform-origin: top;
  pointer-events: none;
  transition: opacity 600ms ease, transform 600ms ease,
    visibility 0s linear 600ms;
}
.loop-widget[data-open="true"] .loop-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
  transition: opacity 280ms ease, transform 280ms ease;
}
.loop-seed-row,
.loop-velocity-row,
.loop-grain-row,
.loop-shades-row {
  display: grid;
  grid-template-columns: 5ch max-content max-content;
  align-items: baseline;
  column-gap: 0.65rem;
}
.loop-velocity-row,
.loop-grain-row,
.loop-shades-row { margin-top: var(--loop-gap); }
.loop-seed-row { height: 1.6em; }
.loop-grain-row,
.loop-shades-row { height: 1.6em; }
.loop-step {
  appearance: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
}
/* Names share the ink of their letters and stay a little quieter than the values. */
.loop-setting-name { color: inherit; opacity: 0.68; text-align: left; }
/* A row line runs from the name to the end of its value (JS sets width and ink).
   It draws and retracts like the canvas lines of the other labels.
   Hover only where a real pointer can hover; touch taps add .loop-tapped instead. */
.loop-underline {
  position: absolute;
  left: 0;
  top: 1.6em;
  width: 0;
  height: 1px;
  pointer-events: none;
  background-color: #e8e8e8;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 420ms cubic-bezier(0.45, 0, 0.55, 1);
}
@media (hover: hover) {
  .loop-menu > :hover > .loop-underline { clip-path: inset(0); }
}
.loop-menu > .loop-tapped > .loop-underline { clip-path: inset(0); }
.loop-velocity { display: inline-block; text-align: left; }
.loop-shades-value { display: inline-block; text-align: left; }
.loop-toggle-row {
  display: grid;
  grid-template-columns: 5ch 1.5ch;
  align-items: baseline;
  column-gap: 0.65rem;
  margin-top: var(--loop-gap);
  height: 1.6em;
}
.loop-dot {
  appearance: none;
  width: 1.5ch;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
  line-height: inherit;
  text-align: center;
}
.loop-dot:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }
.loop-step:focus-visible { outline: 1px solid currentColor; outline-offset: 4px; }
.loop-number {
  width: 5ch;
  height: 100%;
  padding: 0;
  border: 0;
  border-bottom: 1px solid #777;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: right;
}
.loop-number[hidden] { display: none; }
.loop-number:focus-visible { outline: 0; }
.loop-grain-percent { white-space: nowrap; }
.loop-grain-percent[hidden],
.loop-grain-smooth[hidden],
.loop-grain-full[hidden] { display: none; }
.loop-grain-number {
  width: 2ch;
  padding: 0;
  border: 0;
  border-bottom: 1px solid #777;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: right;
}
.loop-grain-number:focus-visible { outline: 0; }
/* The whole row toggles its setting: the row control stretches an invisible hit area
   across the row, while the number inputs stay on top and remain editable. */
.loop-seed-row,
.loop-velocity-row,
.loop-grain-row,
.loop-shades-row,
.loop-toggle-row { position: relative; }
.loop-step::after,
.loop-dot::after {
  content: "";
  position: absolute;
  inset: calc(var(--loop-gap) / -2) 0;
}
.loop-number,
.loop-grain-number { position: relative; z-index: 1; }
/* Letters take the canvas ink pixel by pixel: JS supplies a radial ink map
   that is clipped to the glyphs, so a circle edge can split a single letter. */
.loop-menu .loop-ink {
  --loop-ink: #e8e8e8;
  color: transparent;
  background-color: transparent;
  background-image: linear-gradient(var(--loop-ink), var(--loop-ink));
  -webkit-background-clip: text;
  background-clip: text;
  caret-color: var(--loop-ink);
  text-decoration-color: var(--loop-ink);
  outline-color: var(--loop-ink);
}
.loop-menu .loop-ink[data-ink="dark"] { --loop-ink: #181818; }
/* The ink map only covers the element box, so names must not overflow their column. */
.loop-menu .loop-setting-name.loop-ink { width: max-content; }

.loop-widget,
.soon,
.animation,
.film-grain,
.block-hash,
.copy-status,
.contact-card {
  transition: opacity 1500ms ease, visibility 0s;
}
/* Focus fades are painted on the canvas; JS hides the hit areas while a label is hidden. */
[data-ui-hidden="true"] {
  visibility: hidden !important;
  pointer-events: none !important;
}

@media (max-height: 420px) {
  .loop-widget { --loop-gap: 0.35rem; }
}

@media (prefers-reduced-motion: reduce) {
  .loop-menu,
  .loop-widget[data-open="true"] .loop-menu,
  .loop-underline,
  .loop-widget,
  .soon,
  .block-hash,
  .copy-status,
  .contact-card { transition: none; }
}
