/* CPAL-1.0 License. See chaosaccelerator.com/license.html */

/* The document pages (index, gallery, other projects, readme, license, error).
   The app's palette is copied, not imported: the app's sheets pin html/body
   to the window's height, wrong for a page that scrolls. */
:root {
  --bg: #14161c;
  --bg-panel: #1b1e27;
  --border: #2c3040;
  --text: #e6e8ef;
  --text-dim: #9399ad;
  --accent: #5b8cff;
  --accent-hover: #75a0ff;
}

* { box-sizing: border-box; }

html { background: var(--bg); }
body {
  margin: 0;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

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

.page {
  max-width: 980px;
  margin: 0 auto;
  /* Safe-area insets: these pages keep viewport-fit=cover. */
  padding: max(10px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) 72px max(20px, env(safe-area-inset-left));
}

/* A page whose middle runs the whole window width (the gallery carousel). */
.page-wide {
  max-width: none;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.page-wide .section { max-width: 980px; margin-left: auto; margin-right: auto; }

/* Site name, lower right; same mark as #watermark in app-shell.css. */
/* Bottom gap for the watermark and '80s switch; phones get room above the gesture bar. */
:root { --corner-bottom: calc(env(safe-area-inset-bottom, 0px) + 10px); }
@media (pointer: coarse) {
  :root { --corner-bottom: max(36px, calc(env(safe-area-inset-bottom, 0px) + 14px)); }
}
.watermark {
  position: fixed;
  right: 12px;
  bottom: calc(var(--corner-bottom) - 2px);
  z-index: 2000;
  color: #fff;
  font-size: 12px;
  /* The '80s switch's height, so the two share a middle. */
  line-height: 24px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  pointer-events: none;
  user-select: none;
}
a.watermark { pointer-events: auto; text-decoration: none; }
a.watermark:hover { color: #fff; text-decoration: none; }

/* ---- The page head: back link, title and corner menu on one row ---- */
.page-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  margin-bottom: 28px;
}
.page-head .back-link { margin: 0; justify-self: start; }
.page-head h1 {
  margin: 0;
  font-size: clamp(24px, 4vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 800;
  text-align: center;
}
.page-head .corner-menu { position: relative; top: auto; right: auto; justify-self: end; }

/* ---- Masthead ---- */

.masthead { text-align: center; margin-bottom: 40px; }

.masthead h1 {
  margin: 0;
  font-size: clamp(38px, 7vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-weight: 800;
}
.masthead h1 a {
  background: linear-gradient(135deg, #ffd23f, #ff6b35 55%, #ff2e63);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-decoration: none;
}
.masthead h1 a:hover { filter: brightness(1.12); text-decoration: none; }

.tagline {
  margin: 14px auto 0;
  max-width: 34em;
  font-size: clamp(17px, 2.4vw, 21px);
  color: var(--text);
}

.credits {
  margin: 18px 0 0;
  font-size: 14px;
  color: var(--text-dim);
}
.credits a, .credits a:hover { color: inherit; text-decoration: none; }
.credits p { margin: 2px 0; }

/* ---- Sections ---- */

.section { margin-top: 48px; }

.section-lead {
  margin: 0 0 14px;
  font-size: 17px;
  font-weight: 500;
  text-align: center;
  color: var(--text);
}

/* 16:9 via aspect-ratio, NOT padding-top: a % padding is of the PARENT's width. */
.video {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #000;
}
.video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* ---- The way in ---- */

/* A copy of .fractalize-btn (physics.css); change both together. */
.fractalize-btn {
  display: inline-block;
  font-family: inherit;
  font-size: 17px;
  font-weight: 700;
  padding: 14px 34px;
  border-radius: 999px;
  border: none;
  color: #200b00;
  background: linear-gradient(135deg, #ffd23f, #ff6b35 55%, #ff2e63);
  box-shadow: 0 4px 18px rgba(255, 107, 53, 0.55);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  animation: fractalizePulse 2.2s ease-in-out infinite;
  transition: transform 0.12s ease, box-shadow 0.12s ease, filter 0.12s ease;
}
.fractalize-btn:hover {
  color: #200b00;
  text-decoration: none;
  transform: translateY(-2px) scale(1.05);
  filter: brightness(1.08);
  box-shadow: 0 6px 26px rgba(255, 46, 99, 0.8);
}
.fractalize-btn:active { transform: translateY(0) scale(0.97); }
@keyframes fractalizePulse {
  0%, 100% { box-shadow: 0 4px 18px rgba(255, 107, 53, 0.55); }
  50% { box-shadow: 0 4px 30px rgba(255, 46, 99, 0.9); }
}
.fractalize-btn.large { font-size: 22px; padding: 18px 48px; }
@media (prefers-reduced-motion: reduce) {
  .fractalize-btn { animation: none; }
}

/* ---- Other projects ---- */

.back-link { display: inline-block; margin: 0 56px 28px 0; padding: 12px 0; font-size: 14px; line-height: 16px; }

/* The gallery's carousel with a video on each slide. */
.carousel.projects { --slide-w: min(720px, 86vw); }
.project .video { border: 0; border-bottom: 1px solid var(--border); border-radius: 0; }
.project:not(.is-current) iframe { pointer-events: none; }
.project-caption { padding: 12px 16px 14px; }
.project-caption h2 { margin: 0 0 4px; font-size: 20px; }
.project-caption p { margin: 0; font-size: 15px; color: var(--text-dim); }

/* ---- The license page ---- */

/* The LICENSE text as written: monospaced, line breaks kept, but wrapped for phones. */
.license-text {
  margin: 0;
  padding: 20px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--text);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 12px;
}

/* ---- The gallery ---- */

/* Carousel: a snap scroll container, so swipe, wheel and keyboard just work.
   Slides are narrower than the track, padded at both ends by the difference so
   first and last can center. px and vw, not %: a % here is of the content box. */
.carousel { --slide-w: min(520px, 82vw); }
.carousel-window { position: relative; }
.carousel-track {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  padding-inline: calc((100% - var(--slide-w)) / 2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  outline: none;
}
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-track:focus-visible .slide.is-current { box-shadow: 0 0 0 2px var(--accent); }
.carousel-note {
  flex: 0 0 100%;
  margin: 0;
  padding: 48px 20px;
  text-align: center;
  color: var(--text-dim);
}
.slide {
  flex: 0 0 var(--slide-w);
  scroll-snap-align: center;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-panel);
  color: var(--text);
  text-decoration: none;
  opacity: 0.55;
  transition: opacity 0.25s ease;
}
.slide.is-current { opacity: 1; }
.slide:hover { color: var(--text); text-decoration: none; }
/* The whole map in a fixed square: submissions are any shape, never cropped. */
.slide-frame { position: relative; aspect-ratio: 1 / 1; background: #0c0d11; }
.slide-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.slide-scene {
  position: absolute;
  left: 12px;
  bottom: 12px;
  width: 24%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #0c0d11;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.55);
}
.slide-caption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 12px 16px 14px;
}
.slide-name { font-size: 17px; font-weight: 600; }
.slide-by { font-size: 17px; color: #fff; white-space: nowrap; }

.carousel-arrow {
  position: absolute;
  top: calc(50% - 46px);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0 0 4px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: rgba(20, 22, 28, 0.8);
  color: var(--text);
  font-family: inherit;
  font-size: 30px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.carousel-arrow.prev { left: max(0px, calc(50% - var(--slide-w) / 2 - 56px)); }
.carousel-arrow.next { right: max(0px, calc(50% - var(--slide-w) / 2 - 56px)); }
.carousel-arrow:hover { background: rgba(20, 22, 28, 0.95); border-color: var(--accent); }
.carousel-arrow:disabled { opacity: 0.3; cursor: default; }
.carousel-dots { display: flex; justify-content: center; margin: 12px 0 0; }
/* A 10px dot inside a 24px button, for a finger. */
.carousel-dots button {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.carousel-dots button::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  margin: 0 auto;
  border-radius: 50%;
  background: var(--border);
}
.carousel-dots button[aria-current="true"]::before { background: var(--accent); }
/* One pattern: nothing to step between. */
.carousel:not(.has-many) .carousel-arrow,
.carousel:not(.has-many) .carousel-dots { display: none; }
/* Touch swipes instead; arrows would only cover the picture. */
@media (hover: none) and (pointer: coarse) {
  .carousel-arrow { display: none; }
}

.submit p { margin: 0; text-align: center; font-size: 17px; }

.mail-dialog {
  width: min(92vw, 560px);
  margin: auto;
  padding: 18px 22px 20px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-panel);
  color: var(--text);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
}
.mail-dialog::backdrop { background: rgba(0, 0, 0, 0.6); }
.mail-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.mail-dialog-head h2 { margin: 0; font-size: 20px; line-height: 1.3; }
.mail-dialog-close {
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0 0 2px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.mail-dialog-close:hover { background: var(--bg); color: var(--text); }
.mail-field-label {
  padding-top: 7px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
}
.mail-field-value {
  margin: 0;
  padding: 7px 10px;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  user-select: all;
}
.mail-copy {
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.mail-copy:hover { background: var(--bg); border-color: var(--accent); }
.mail-dialog-actions { margin-top: 14px; text-align: right; font-size: 14px; }
.mail-dialog :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 480px) {
  .mail-field { grid-template-columns: minmax(0, 1fr) auto; }
  .mail-field-label { grid-column: 1 / -1; padding-top: 0; }
}

/* ---- The landing page: one screen ---- */

/* index.html is one screen: masthead, the tour (a sideways carousel), dots and
   credits. Vertical sizes are in vh so a short window shrinks type and gaps. */
body.landing {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
}
.screen {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: env(safe-area-inset-top) max(16px, env(safe-area-inset-right)) max(10px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
.landing .masthead { flex: none; margin: 0; padding-top: clamp(8px, 2vh, 20px); }
/* Under the corner menu's button: no room beside a 30px title on a phone. */
@media (max-width: 640px) {
  .landing .masthead { padding-top: 48px; }
}
.landing .masthead h1 { font-size: clamp(30px, min(7vw, 8.5vh), 60px); }
.landing .tagline {
  margin-top: clamp(6px, 1.2vh, 12px);
  font-size: clamp(14px, min(2.2vw, 2.4vh), 19px);
  line-height: 1.35;
}
.landing .tagline a { color: inherit; }
.landing .tagline a:hover { color: inherit; text-decoration: underline; }
.landing .launch { margin: clamp(10px, 2vh, 20px) 0 clamp(12px, 2.4vh, 24px); }
.landing .fractalize-btn.large {
  font-size: clamp(16px, 2.6vh, 22px);
  padding: clamp(11px, 2vh, 18px) clamp(30px, 5.5vh, 48px);
}

/* The tour fills what masthead and foot leave. --slide-w: as wide as the window
   allows, but no wider than fits a 16:9 picture over a caption in that height
   (cqh; a browser without it keeps the width rule and crops). Also pads the track. */
.tour {
  position: relative;
  flex: 1;
  min-height: 0;
  container-type: size;
  --slide-w: min(100%, 780px);
}
@supports (width: 1cqh) {
  .tour { --slide-w: min(100%, 780px, calc((100cqh - 84px) * 16 / 9)); }
}
.tour-track {
  position: relative;
  display: flex;
  align-items: center;
  gap: 24px;
  height: 100%;
  padding-inline: calc((100% - var(--slide-w)) / 2);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  outline: none;
}
.tour-track::-webkit-scrollbar { display: none; }
/* A slide is as tall as its content and centered in the track; off-center slides dimmed. */
.tour-slide {
  display: flex;
  flex: 0 0 var(--slide-w);
  flex-direction: column;
  max-height: 100%;
  scroll-snap-align: center;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-panel);
  color: var(--text);
  opacity: 0.55;
  transition: opacity 0.25s ease;
}
.tour-slide.is-current { opacity: 1; }
/* Edge slides center only when clicked: their video would take the click. */
.tour-slide:not(.is-current) iframe { pointer-events: none; }
.tour-track:focus-visible .tour-slide.is-current { box-shadow: 0 0 0 2px var(--accent); }
/* The 16:9 picture shrinks (the caption never does) when the slide is taller than the track. */
.tour-media {
  position: relative;
  flex: 0 1 auto;
  min-height: 0;
  aspect-ratio: 16 / 9;
  background: #0c0d11;
  border-bottom: 1px solid var(--border);
}
.tour-media.video { border-radius: 0; border-width: 0 0 1px; }
.tour-media > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tour-link {
  display: flex;
  flex-direction: column;
  min-height: 0;
  color: inherit;
  text-decoration: none;
}
.tour-link:hover { color: inherit; text-decoration: none; }
.tour-link:hover .tour-caption h2 { text-decoration: underline; }
.tour-step {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 8px 20px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: rgba(12, 13, 17, 0.82);
  color: var(--text);
  font-size: clamp(42px, 6.2vh, 50px);
  font-weight: 600;
  line-height: 1.3;
}
.tour-caption { flex: none; padding: 11px 16px 13px; }
.tour-caption h2 {
  margin: 0;
  font-size: clamp(15px, 2.2vh, 18px);
  font-weight: 600;
  line-height: 1.3;
}
.tour-caption p {
  margin: 3px 0 0;
  font-size: clamp(13px, 1.9vh, 15px);
  line-height: 1.45;
  color: var(--text-dim);
}
.gallery-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  grid-auto-rows: minmax(0, 1fr);
  gap: 12px;
  padding: 12px;
}
.gallery-card {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.12s ease;
}
.gallery-card:hover { color: var(--text); text-decoration: none; border-color: var(--accent); }
.gallery-card-frame {
  position: relative;
  flex: 1;
  min-height: 0;
  background: #0c0d11;
  border-bottom: 1px solid var(--border);
}
.gallery-card-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gallery-card-scene.gallery-card-scene {
  inset: auto auto 8px 8px;
  width: 26%;
  height: auto;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #0c0d11;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.55);
}
.gallery-card span {
  display: block;
  padding: 7px 10px 8px;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tour .carousel-arrow { top: 50%; transform: translateY(-50%); }
.tour .carousel-arrow.prev { left: max(0px, calc(50% - var(--slide-w) / 2 - 56px)); }
.tour .carousel-arrow.next { right: max(0px, calc(50% - var(--slide-w) / 2 - 56px)); }

.foot { flex: none; padding-top: clamp(4px, 1vh, 10px); text-align: center; }
.landing .carousel-dots { margin: 0; }
.landing .credits {
  margin: 2px 0 0;
  font-size: clamp(11px, 1.6vh, 13px);
  line-height: 1.5;
}

/* ---- The corner menu ---- */

/* One button at the top right and the list it drops down. */
.corner-menu {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  right: max(12px, env(safe-area-inset-right));
  z-index: 5;
}
.corner-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: rgba(27, 30, 39, 0.85);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.corner-menu-btn:hover,
.corner-menu-btn[aria-expanded="true"] { background: var(--bg-panel); border-color: var(--accent); }
.corner-menu-list {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  margin: 0;
  padding: 6px;
  list-style: none;
  min-width: 250px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}
.corner-menu-list a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 14px;
  white-space: nowrap;
  color: var(--text);
  text-decoration: none;
}
.corner-menu-list a:hover { background: var(--bg); color: var(--text); text-decoration: none; }
/* Icons in the text color, not brand colors. */
.corner-menu-list svg { flex: none; width: 18px; height: 18px; color: var(--text); }
/* The bat is 3:1, so it gets more width, taken from the margins. */
.corner-menu-list svg.wide { width: 24px; margin: 0 -3px; }

/* ---- The readme page ---- */

/* README.md rendered as a page: the document's own headings, no masthead. */
.readme h1 {
  margin: 0 0 12px;
  font-size: clamp(34px, 6vw, 52px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 800;
}
.readme h2 { margin: 36px 0 10px; font-size: 24px; line-height: 1.2; }
.readme h3 { margin: 28px 0 8px; font-size: 19px; line-height: 1.3; }
.readme h4, .readme h5, .readme h6 { margin: 22px 0 6px; font-size: 16px; }
.readme p, .readme ul, .readme ol, .readme blockquote { margin: 0 0 16px; }
.readme li { margin: 4px 0; }
.readme blockquote {
  padding: 2px 16px;
  border-left: 3px solid var(--border);
  color: var(--text-dim);
}
.readme hr { margin: 28px 0; border: 0; border-top: 1px solid var(--border); }
.readme img { max-width: 100%; height: auto; border-radius: 8px; }
.readme code {
  padding: 2px 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 5px;
}
.readme pre {
  margin: 0 0 16px;
  padding: 14px 16px;
  overflow-x: auto;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.readme pre code { padding: 0; border: 0; background: none; font-size: 13px; }
.readme .readme-note { color: var(--text-dim); }
