/* Screen Island. Layout utilities come from Tachyons Neo; this file holds the
   themes and the parts Tachyons doesn't have opinions on: the bar, the tiles and
   the room. A theme only sets the tokens below. The room's palette lives in
   island.js and swaps along with them. */

@font-face {
  font-family: "Jersey 15";
  src: url("/assets/fonts/Jersey15.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/JetBrainsMono-Variable.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  --gap: 8px;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --pixel: "Jersey 15", var(--mono);
  --px: 3px;
  --say: #fff0a8;
}

:root, [data-theme="dusk"] {
  color-scheme: dark;
  --bg: #17143f;
  --bg-deep: #0f0c2e;
  --tile: #1d194d;
  --line: #3b3470;
  --active: #ffb454;
  --text: #f7e7c8;
  --muted: #bdb3e0;
  --accent: #ffb454;
  --verb: #6fdcc8;
  --hot: #fff0a8;
  --title: #fff4d6;
  --title-shadow: #2a1560;
}
[data-theme="plankton"] {
  color-scheme: dark;
  --bg: #050d1a;
  --bg-deep: #030812;
  --tile: #081427;
  --line: #17425a;
  --active: #3dffe2;
  --text: #d9fbff;
  --muted: #93c8d4;
  --accent: #3dffe2;
  --verb: #84aeff;
  --hot: #ff8adf;
  --title: #effdff;
  --title-shadow: #0b4254;
}
[data-theme="tokyo-night"] {
  color-scheme: dark;
  --bg: #1a1b26;
  --bg-deep: #13141c;
  --tile: #1f2230;
  --line: #414868;
  --active: #7aa2f7;
  --text: #c0caf5;
  --muted: #a9b1d6;
  --accent: #9ece6a;
  --verb: #7aa2f7;
  --hot: #e0af68;
  --title: #c0caf5;
  --title-shadow: #13141c;
}
[data-theme="gruvbox"] {
  color-scheme: dark;
  --bg: #282828;
  --bg-deep: #1d2021;
  --tile: #32302f;
  --line: #504945;
  --active: #fabd2f;
  --text: #ebdbb2;
  --muted: #bdae93;
  --accent: #fabd2f;
  --verb: #83a598;
  --hot: #fe8019;
  --title: #fbf1c7;
  --title-shadow: #076678;
}
[data-theme="rose-pine"] {
  color-scheme: light;
  --bg: #f2e9e1;
  --bg-deep: #e6dcd3;
  --tile: #fffaf3;
  --line: #dfdad9;
  --active: #b4637a;
  --text: #575279;
  --muted: #615d7c;
  --accent: #9a4560;
  --verb: #1f5a72;
  --hot: #9a4560;
  --title: #464168;
  --title-shadow: #fffaf3;
}
[data-theme="everforest"] {
  color-scheme: dark;
  --bg: #2d353b;
  --bg-deep: #232a2e;
  --tile: #343f44;
  --line: #475258;
  --active: #a7c080;
  --text: #d3c6aa;
  --muted: #b5b09a;
  --accent: #a7c080;
  --verb: #7fbbb3;
  --hot: #dbbc7f;
  --title: #fdf6e3;
  --title-shadow: #2d353b;
}
[data-theme="nord"] {
  color-scheme: dark;
  --bg: #2e3440;
  --bg-deep: #242933;
  --tile: #3b4252;
  --line: #4c566a;
  --active: #88c0d0;
  --text: #eceff4;
  --muted: #c3cbd9;
  --accent: #88c0d0;
  --verb: #8fbcbb;
  --hot: #ebcb8b;
  --title: #eceff4;
  --title-shadow: #2e3440;
}
[data-theme="phosphor"] {
  color-scheme: dark;
  --bg: #07120b;
  --bg-deep: #040b07;
  --tile: #0b1a10;
  --line: #1d4a2c;
  --active: #5dff8f;
  --text: #b9ffc9;
  --muted: #7fd898;
  --accent: #5dff8f;
  --verb: #5dff8f;
  --hot: #e6ffe9;
  --title: #e6ffe9;
  --title-shadow: #0c2a16;
}

/* ---- base ------------------------------------------------------------- */

html {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
}
body {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  background: var(--bg);
  font-size: .9375rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--pixel);
  font-weight: 400;
  line-height: 1;
  color: var(--title);
}
a { color: var(--accent); text-underline-offset: .2em; }
a:hover { color: var(--hot); }
:focus-visible { outline: 2px solid var(--hot); outline-offset: 2px; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

.muted { color: var(--muted); }
.small { font-size: .8125rem; }

/* ---- the bar ----------------------------------------------------------- */

.bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  min-height: 2.5rem;
  padding: 0 calc(var(--gap) + .25rem);
  background: var(--bg-deep);
  color: var(--muted);
  font-size: .8125rem;
}
.ws { gap: 1.25rem; }
.ws a { display: inline-block; padding: .5rem 0; color: var(--muted); text-decoration: none; white-space: nowrap; }
.ws a:hover { color: var(--text); }
.ws a[aria-current] { color: var(--title); box-shadow: inset 0 -2px 0 var(--active); }
.ws-n { color: var(--accent); }
.clock { white-space: nowrap; }
.theme-btn { padding: .5rem 0; white-space: nowrap; }
.theme-btn:hover { color: var(--text); }
.theme-btn + .theme-btn { margin-left: 1.25rem; }

.toast {
  position: fixed;
  top: 3rem;
  right: var(--gap);
  z-index: 30;
  margin: 0;
  padding: .5rem .875rem;
  background: var(--tile);
  border: 2px solid var(--active);
}

/* ---- tiles -------------------------------------------------------------
   Windows on a tiling desktop: flat, square, a gap between them. Focus follows
   the mouse, so the border switches instantly and without a transition. */

.desk { display: flex; flex-direction: column; flex: 1; gap: var(--gap); padding: 0 var(--gap); }

.tile {
  --pad-x: 1.5rem;
  --pad-y: 1.25rem;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--pad-y) var(--pad-x);
  background: var(--tile);
  border: 2px solid var(--line);
}
.tile:hover, .tile:focus-within, .tile:target { border-color: var(--active); }
.tile p { max-width: 62ch; margin: .75rem 0 0; }
.tile h3 { font-size: 2.5rem; }
.tile h2 { font-size: 3.5rem; }

.tag { color: var(--muted); }
.tile .tag { margin-top: .25rem; }
.tile .out { margin-top: auto; padding-top: 1rem; }

/* a window onto the island, full-bleed at the top of a tile */
.scene {
  flex: none;
  height: calc(var(--h) * var(--s) * 1px);
  margin: calc(var(--pad-y) * -1) calc(var(--pad-x) * -1) 1.125rem;
  overflow: hidden;
  background: var(--bg-deep);
}
.scene canvas { display: block; max-width: none; image-rendering: pixelated; }

.dwindle { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr); }

.statement h2 { font-size: clamp(3.25rem, 8vw, 7rem); line-height: .9; max-width: 8em; }
.statement .manifesto { margin-top: 1.25rem; font-family: var(--pixel); font-size: 2rem; line-height: 1.1; color: var(--title); max-width: 26em; }
.statement .scene { margin: auto calc(var(--pad-x) * -1) calc(var(--pad-y) * -1); }
.statement p + .scene { margin-top: auto; }
.statement > p:last-of-type { margin-bottom: 1.25rem; }
.flagship h3 { font-size: 4rem; }
.shelf { margin: 1rem 0 0; padding: 0; list-style: none; }
.shelf li { padding: .1rem 0; overflow-wrap: anywhere; }

.bench { width: 100%; margin-top: 1.125rem; border-collapse: collapse; font-size: .8125rem; }
.bench caption { padding-bottom: .375rem; text-align: left; color: var(--muted); }
.bench th, .bench td { padding: .15rem 0; text-align: right; font-weight: 400; font-variant-numeric: tabular-nums; }
.bench tbody th { text-align: left; }
.bench tbody th span { color: var(--muted); }
.bench thead th { color: var(--muted); }
.bench th:first-child, .bench thead td { width: 42%; }
.bench tbody td:nth-child(2) { color: var(--accent); }

@container (min-width: 56em) {
  .dwindle {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }
  .d1 { grid-column: 1 / 7; grid-row: 1 / 3; }
  .d2 { grid-column: 7 / 13; grid-row: 1; }
  .dg { grid-column: 7 / 13; grid-row: 2; }
  .third { grid-column: span 4; }
  .flip .d1 { grid-column: 7 / 13; }
  .flip .d2 { grid-column: 1 / 7; grid-row: 1; }
  .flip .d3 { grid-column: 1 / 7; grid-row: 2; }
  .shelf { columns: 2; column-gap: 2rem; }
}

/* install commands */
.cmd {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  padding: .625rem .75rem;
  background: var(--bg-deep);
  color: var(--verb);
  font-size: .8125rem;
  line-height: 1.5;
}
.cmd code { font-family: inherit; overflow-wrap: anywhere; color: inherit; }
.cmd button { flex: none; color: var(--muted); }
.cmd button:hover { color: var(--hot); }
.cmd button::before { content: none; }

/* logbook */
.log h2 { margin-bottom: 1rem; }
.log li { padding: .35rem 0; }
.log li p { margin: 0 0 .5rem 7em; max-width: 72ch; }
.log li a { display: flex; gap: 1em; text-decoration: none; color: var(--text); }
.log a span { text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: .2em; }
.log a:hover span { color: var(--hot); text-decoration-color: currentColor; }
.log time { flex: none; width: 6em; color: var(--muted); }

/* ---- sub pages --------------------------------------------------------- */

.page-head h1 { font-size: clamp(3rem, 8vw, 5.5rem); line-height: .95; }
.tile .lead { margin-top: .5rem; color: var(--muted); }

.stack { display: flex; flex-direction: column; gap: var(--gap); }
.product { display: flex; flex-direction: column-reverse; padding: 0; }
.product-text { display: flex; flex-direction: column; flex: 1; min-width: 0; padding: var(--pad-y) var(--pad-x); }
.product h2 { font-size: 4rem; }
.product .scene { position: relative; margin: 0; }
.product .scene canvas { position: absolute; top: 0; left: 0; }
.product ul { margin: 1rem 0 0; padding: 0; list-style: none; }
.product li { padding: .2rem 0; color: var(--muted); }
.product li::before { content: "$ "; color: var(--accent); }

.tool-grid { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr); }
.tool-grid .tile h3 { font-size: 2.25rem; }
.tool-grid .tile:last-child:nth-child(odd) { grid-column: 1 / -1; }

@container (min-width: 56em) {
  .product { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .product .scene { height: auto; min-height: 15rem; }
  .stack .product:nth-child(even) .product-text { order: 2; }
  .tool-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* long text */
.prose { width: 100%; max-width: 72ch; margin: 0 auto; }
.prose > h1 { font-size: clamp(2.75rem, 7vw, 4.5rem); line-height: .95; margin: .5rem 0 1.5rem; }
.prose h1 { font-size: 3rem; margin: 2.5rem 0 1rem; }
.prose h2 { font-size: 2.5rem; margin: 2.5rem 0 .75rem; }
.prose h3 { font-size: 1.75rem; margin: 1.75rem 0 .5rem; }
.prose h4 { font-size: 1.5rem; margin: 1.5rem 0 .5rem; }
.prose > :first-child { margin-top: 0; }
.prose > h1 + h1 { display: none; } /* older posts repeat their title in the body */
.prose p, .prose ul, .prose ol, .prose pre, .prose blockquote, .prose table { margin: 1em 0 0; }
.prose ul, .prose ol { padding-left: 1.5em; }
.prose img { max-width: 100%; height: auto; }
.prose blockquote { padding-left: 1em; border-left: 2px solid var(--active); color: var(--muted); }
.prose code { font-family: var(--mono); font-size: .92em; color: var(--verb); }
.prose pre { padding: .875rem 1rem; overflow-x: auto; background: var(--bg-deep); font-size: .8125rem; line-height: 1.55; }
.prose pre code { color: inherit; }
.prose .highlight { background: transparent; }
.prose div.highlight, .prose figure.highlight { margin: 1em 0 0; }
.prose div.highlight pre { background: #122b3b; }

/* ---- the room ----------------------------------------------------------- */

.room-win { padding: 0; border-color: var(--active); background: var(--bg-deep); }
.room { display: flex; justify-content: center; overflow: hidden; }
.stage {
  position: relative;
  flex: none;
  width: 100%;
  height: calc(170 * var(--px));
  overflow: hidden;
  background: linear-gradient(var(--bg-deep), var(--bg));
  cursor: crosshair;
}
.stage canvas { display: block; max-width: none; image-rendering: pixelated; }

.world { position: absolute; top: 0; left: 0; width: calc(480 * var(--px)); height: 100%; }
.hot {
  position: absolute;
  left: calc(var(--x) * var(--px));
  top: calc(var(--y) * var(--px));
  width: calc(var(--w) * var(--px));
  height: calc(var(--h) * var(--px));
  cursor: crosshair;
}
.hot:focus-visible { outline: 2px dashed var(--hot); outline-offset: 0; }

.title {
  position: absolute;
  top: calc(9 * var(--px));
  right: calc(16 * var(--px));
  width: min(calc(166 * var(--px)), 100% - 2rem);
  pointer-events: none;
}
.room-win[data-room="source"] .title { right: auto; left: calc(14 * var(--px)); width: min(calc(150 * var(--px)), 100% - 2rem); }
.title h1 {
  font-size: calc(30 * var(--px));
  line-height: .86;
  color: var(--title);
  text-shadow: var(--px) var(--px) 0 var(--title-shadow);
}
.title p {
  margin: calc(3 * var(--px)) 0 0;
  max-width: 30em;
  color: var(--title);
  font-family: var(--pixel);
  font-size: calc(8 * var(--px));
  line-height: 1.05;
  text-shadow: 2px 0 0 var(--title-shadow), -2px 0 0 var(--title-shadow), 0 2px 0 var(--title-shadow), 0 -2px 0 var(--title-shadow);
}

.say[data-who="parrot"] { bottom: calc(84 * var(--px)); color: #ffb3c7; }
.say {
  position: absolute;
  bottom: calc(50 * var(--px));
  left: 0;
  z-index: 2;
  width: max-content;
  max-width: 90%;
  margin: 0;
  transform: translateX(-50%);
  text-align: center;
  font-family: var(--pixel);
  font-size: 1.5rem;
  line-height: 1.05;
  color: var(--say);
  text-shadow: 2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 2px 2px 0 #000, -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000;
  pointer-events: none;
}

/* In a cutscene the verbs go away, like they always did, and a click skips it. */
.room-win[data-cutscene] .stage { cursor: pointer; }
.room-win[data-cutscene] .world { pointer-events: none; }
.room-win[data-cutscene] .verbs, .room-win[data-cutscene] .inv { visibility: hidden; }
.room-win[data-dialogue] .verbs, .room-win[data-dialogue] .inv { display: none; }

/* what the islander could say instead */
.lines { grid-column: 1 / -1; margin: 0; padding: 0; list-style: none; }
.lines button { display: block; width: 100%; padding: .1rem 0; text-align: left; color: var(--verb); }
.lines button:hover, .lines button:focus-visible { color: var(--hot); outline: none; }

/* the terminal, a floating window that drops down from behind the bar.
   Only transform and visibility change, so the compositor runs the slide at the display's
   refresh rate, whatever the island's canvas is doing on the main thread. */
.quake {
  position: fixed;
  top: 2.5rem;
  right: var(--gap);
  left: var(--gap);
  z-index: 15;
  display: flex;
  flex-direction: column;
  height: min(52vh, 28rem);
  padding: .75rem 1rem;
  background: var(--bg-deep);
  border: 2px solid var(--active);
  font-family: var(--mono);
  font-size: .875rem;
  line-height: 1.5;
  color: var(--text);
  visibility: hidden;
  transform: translate3d(0, -100%, 0);
  transition: transform .2s cubic-bezier(.4, 0, .7, .2), visibility 0s linear .2s;
  will-change: transform;
}
.quake.open {
  visibility: visible;
  transform: translate3d(0, 0, 0);
  transition: transform .28s cubic-bezier(.32, .72, 0, 1), visibility 0s;
}
.quake-log { flex: 1; min-height: 0; overflow-y: auto; }
.quake pre { margin: 0; padding: 0; background: none; font: inherit; color: inherit; white-space: pre-wrap; overflow-wrap: anywhere; }
.quake pre.said { color: var(--accent); }
.quake pre.dim { color: var(--muted); }
.quake-line { display: flex; gap: .625rem; align-items: baseline; margin: .25rem 0 0; }
.quake-line label { flex: none; max-width: 60%; overflow: hidden; color: var(--accent); white-space: nowrap; text-overflow: ellipsis; }
.quake-line input { flex: 1; min-width: 0; padding: 0; border: 0; outline: 0; background: none; font: inherit; color: var(--text); caret-color: var(--hot); }
@media (prefers-reduced-motion: reduce) { .quake, .quake.open { transition: none; } }
@media (pointer: coarse) { .quake-line input { font-size: 16px; } }

/* the verb console, as low on the screen as it always was */
.console {
  display: none;
  grid-template-columns: minmax(0, 1fr);
  gap: .25rem 2.5rem;
  padding: .5rem 1rem .75rem;
  background: var(--bg-deep);
  font-family: var(--pixel);
  font-size: 1.5rem;
  line-height: 1.15;
}
.js .console { display: grid; }
.sentence { margin: 0; min-height: 1.15em; color: var(--title); }
.skip { font-family: var(--mono); font-size: .8125rem; line-height: 1.8; }
.verbs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 1rem; }
.verbs button { padding: .1rem 0; text-align: left; color: var(--verb); white-space: nowrap; }
.verbs button:focus-visible, .inv a:focus-visible { outline-offset: 0; }
.verbs button:hover, .verbs [aria-pressed="true"] { color: var(--hot); }
.inv { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1rem; margin: .5rem 0 0; padding: 0; }
.inv a { display: block; padding: .1rem 0; color: var(--accent); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inv a:hover { color: var(--hot); }
.inv button { display: block; padding: .1rem 0; color: var(--hot); white-space: nowrap; }

@container (min-width: 40em) {
  .console { grid-template-columns: auto minmax(0, 1fr); }
  .skip { justify-self: end; }
  .verbs { width: max-content; column-gap: 2rem; }
  .inv { grid-template-columns: repeat(3, max-content); column-gap: 3rem; margin-top: 0; align-content: start; }
}
@container (max-width: 39.99em) {
  .skip { order: 9; }
  .sentence { order: -1; }
}

/* Without JavaScript there is no island to draw, so the title stands on its own. */
html:not(.js) .stage { width: 100%; height: auto; padding: 2rem 1.5rem; cursor: auto; }
html:not(.js) .stage canvas, html:not(.js) .world, html:not(.js) .scene, html:not(.js) .theme-btn { display: none; }
html:not(.js) .title { position: static; width: auto; }

/* ---- footer ------------------------------------------------------------- */

.foot { gap: .75rem 2rem; margin: 0 var(--gap) var(--gap); font-size: .8125rem; }
.foot p { max-width: none; }
.foot-links { gap: .25rem 1.25rem; }

/* ---- small screens ------------------------------------------------------- */

@container (max-width: 39.99em) {
  .bar { grid-template-columns: minmax(0, 1fr) auto; gap: .5rem; }
  .clock { display: none; }
  .ws { gap: .875rem; }
  .ws-n { display: none; }
  .theme-btn .ws-n { display: inline; }
  .tile { --pad-x: 1.125rem; --pad-y: 1rem; }
  .tile h2 { font-size: 3rem; }
  .flagship h3 { font-size: 3rem; }
  .statement .manifesto { font-size: 1.625rem; }
  .title, .room-win[data-room="source"] .title { top: calc(5 * var(--px)); right: auto; left: 1rem; width: calc(100% - 2rem); }
  .title h1 { font-size: 3rem; }
  .title p { font-size: 1.125rem; max-width: none; }
  .say { font-size: 1.25rem; bottom: calc(44 * var(--px)); }
  .verbs button, .inv a { padding: .3rem 0; }
  .log li a { flex-direction: column; gap: 0; }
  .log li p { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
