/* silkscreen is jason kottke's 8px pixel font, the one everyone had in 2001.
   kept here instead of loading it off google (license in fonts/) */
@font-face { font-family: Silkscreen; src: url(fonts/silkscreen.woff2) format('woff2'); }

/* pixel copies of verdana (and ms gothic for code), one per size, made by
   tools/pixfont.py. each is only right at its own px size, so anything that
   changes size changes font too */
@font-face { font-family: pix13; src: url(fonts/pix13.woff2) format('woff2'); }
@font-face { font-family: pix14; src: url(fonts/pix14.woff2) format('woff2'); }
@font-face { font-family: pix14; src: url(fonts/pix14b.woff2) format('woff2'); font-weight: bold; }
@font-face { font-family: pix14; src: url(fonts/pix14i.woff2) format('woff2'); font-style: italic; }
@font-face { font-family: pix18; src: url(fonts/pix18.woff2) format('woff2'); }
@font-face { font-family: pix24; src: url(fonts/pix24.woff2) format('woff2'); }
@font-face { font-family: pix30; src: url(fonts/pix30.woff2) format('woff2'); }
@font-face { font-family: pix40; src: url(fonts/pix40.woff2) format('woff2'); }
@font-face { font-family: pixgothic13; src: url(fonts/pixgothic13.woff2) format('woff2'); }

html {
  /* how tall the card is (the lander's, measured), and with the footer.
     every page's card is this size, the blog ones scroll inside it. .tall
     has its own */
  --card-h: 560px;
  --lander-h: calc(var(--card-h) + 34px);
  color-scheme: dark;
  background: #070707 repeating-linear-gradient(#070707 0 2px, #2c2c2c 2px 3px);
}
/* body stays see-through so the stripes on html show. some hosts paint
   body white by default (the claude artifact wrapper does) */
body {
  background: none;
  margin: 0;
  box-sizing: border-box;
  min-height: calc(var(--fit-h, 100vh) - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  align-items: center;
  /* every page puts its card where the lander's sits when it's centred on
     the screen, so going from page to page the card stays put and longer
     pages just carry on down past the bottom */
  padding: max(10px, calc((var(--fit-h, 100vh) - var(--lander-h)) / 2)) 0 10px;
  color: #f5efff;
  font: 13px/20px pix13, Verdana, Tahoma, sans-serif;
  /* no smeared fake bold or slanted italic on top of the pixel fonts */
  font-synthesis: none;
}
/* the corner flowers behind everything (blooms() in site.js). drawn small
   and blown up blocky, a bit see through so the stripes still show. the
   top right canvas is turned round so both get laid out from their corner */
.bloom {
  position: fixed;
  z-index: -1;
  opacity: .6;
  image-rendering: pixelated;
  pointer-events: none;
}
.bloom.bl { left: 0; bottom: 0; }
.bloom.tr { right: 0; top: 0; transform: rotate(180deg); }

a { color: inherit; text-decoration: none; }
a:hover { color: #fff; text-decoration: underline; }

/* scrollbars (long posts, code boxes) as flat pixel bars in the flower
   purples with a 2001 bevel, square, no arrows. chrome, edge and safari use
   the ::-webkit ones. firefox can only do colours, so it gets just those */
::-webkit-scrollbar { width: 10px; height: 10px; background: #0d0a10; }
::-webkit-scrollbar-thumb {
  background: #5a3768;
  border: 2px solid;
  border-color: #74467f #3a2444 #3a2444 #74467f;
}
::-webkit-scrollbar-thumb:hover { background: #74467f; }
::-webkit-scrollbar-corner { background: #0d0a10; }
/* inside the card the track is just a darker strip of the card's purple */
#blog::-webkit-scrollbar, #post::-webkit-scrollbar, #comms::-webkit-scrollbar { background: rgba(10, 0, 30, .35); }
@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-color: #5a3768 #0d0a10; }
}

/* the whole site is one card. the purple and the sawtooth run the full
   width of the screen, what's on it stays in a 900px column down the middle
   (the padding). phones get a narrower card, see .tall at the bottom */
#card {
  position: relative;
  align-self: stretch;
  padding: 0 max(0px, calc((100% - 900px) / 2));
  min-height: var(--card-h);
  margin-top: 8px;
  background: linear-gradient(#531fad, #522786 45%, #502e66 80%, #4b3055);
  overflow-x: clip;
}
/* windows chrome draws text with cleartype, which puts red and blue fringes
   down the sides of every pixel. text on its own layer only gets plain
   greyscale smoothing, and the pixel fonts have nothing to smooth, so they
   come out as clean blocks */
#card, #copy { will-change: transform; }

/* the tab row along the top of the card, the old site's nav bar redone: a
   thin boxed strip, pixel labels split by bars, the page you're on lit up
   like the title, contact off on the right */
#tabs {
  display: flex;
  flex: none;
  align-items: center;
  height: 22px;
  margin: 10px 0 0;
  padding: 0 12px;
  border: 1px solid rgba(225,205,255,.4);
  background: rgba(20,0,50,.2);
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  white-space: nowrap;
}
#tabs a { color: #ac8fe8; }
#tabs a + a::before { content: '|'; margin: 0 14px; color: rgba(225,205,255,.3); }
#tabs a:hover { color: #fff; text-decoration: none; }
#tabs a.on { color: #fff; text-shadow: 0 0 3px #dcc8ff, 0 0 8px #a67cff; }
#tabs #contact { display: flex; align-items: center; gap: 6px; margin-left: auto; }
#tabs #contact::before { content: none; }
#tabs svg { flex: none; }

/* sawtooth top + bottom. each one is a single long zigzag (inline svg in
   index.html) instead of a repeated 14px tile: tiled, every seam between
   tiles and the strip's bottom edge got blended with the dark page on hi-dpi
   phones and showed as hairlines. each also reaches 2px into the card in the
   card's own colour so there's no edge left to show through. they hang one
   tooth past each side and slide one tooth over and over so the loop is
   seamless, overflow-x clip on #card hides the extra */
.edge {
  position: absolute;
  z-index: 3;
  left: -14px;
  animation: 3s linear infinite;
}
.edge.top { top: -8px; animation-name: drift-right; }
.edge.bottom { bottom: -8px; animation-name: drift-left; }
@keyframes drift-right { to { transform: translateX(14px); } }
@keyframes drift-left { to { transform: translateX(-14px); } }
@media (prefers-reduced-motion: reduce) {
  .edge { animation: none; }
}

/* art strip. two layers that take turns fading in (see the script at the
   bottom of index.html), fading out of the sawtooth at the top and
   dissolving into the purple below. a short top fade reads as a dark line
   under the teeth, a long one reads as a gradient */
#art {
  --top-fade: 46px;
  /* and out to the sides too, so the strip melts into the purple either
     side of it instead of sitting there as a box */
  --side-fade: linear-gradient(90deg, transparent, #000 80px, #000 calc(100% - 80px), transparent);
  position: relative;
  height: 296px;
  -webkit-mask-image: linear-gradient(transparent, #000 var(--top-fade), #000 55%, transparent), var(--side-fade);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(transparent, #000 var(--top-fade), #000 55%, transparent), var(--side-fade);
  mask-composite: intersect;
}
#art .slide {
  position: absolute;
  inset: 0;
  background: center / cover;
  opacity: 0;
  transition: opacity 2.5s;
}
#art .slide.on { opacity: 1; }
/* faint lavender filter (multiply keeps each piece's own colours, whites
   go soft lavender instead of glaring), scanlines over everything */
#art::before, #art::after {
  content: '';
  position: absolute;
  inset: 0;
}
#art::before {
  z-index: 1;
  background: #c9b2ff;
  mix-blend-mode: multiply;
  opacity: .45;
}
#art::after {
  z-index: 2;
  background: repeating-linear-gradient(transparent 0 2px, rgba(20,0,40,.3) 2px 3px);
}

/* glow + scanlines. the mask stripes the text and its glow but leaves
   whats behind alone, padding is there so the glow (and the hop) dont get
   clipped */
h1 {
  position: relative;
  margin: -68px 0 0;
  padding: 28px 28px 10px;
  cursor: default;
  user-select: none;
  font: normal 40px pix40, Verdana, sans-serif;
  letter-spacing: 7px;
  color: #f7f1ff;
  text-shadow: 0 0 3px #dcc8ff, 0 0 8px #a67cff, 0 0 16px #8a55f0;
  -webkit-mask-image: repeating-linear-gradient(#000 0 2px, rgba(0,0,0,.5) 2px 3px);
  mask-image: repeating-linear-gradient(#000 0 2px, rgba(0,0,0,.5) 2px 3px);
}

h1 .seg {
  display: inline-block;
  position: relative;
  transform-origin: 50% 100%;
}

hr {
  margin: 7px 38px 0;
  border: 0;
  border-top: 1px solid rgba(225,205,255,.45);
}

#about {
  display: flex;
  justify-content: space-between;
  padding: 16px 38px 26px;
}
#about .me { width: 530px; }
#about p { margin: 0 0 14px; }
#about .social { width: 180px; }

/* link rows with a pixel icon in front (pages + social) */
.ico a {
  display: flex;
  align-items: center;
  gap: 10px;
}
.ico svg { flex: none; width: 11px; color: #ac8fe8; }
.ico a:hover svg { color: #fff; }

.label {
  margin-bottom: 4px;
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #ac8fe8;
}

/* the site title on blog pages is a link home, keep it looking like the title */
h1 a, h1 a:hover { color: inherit; text-decoration: none; }

#copy {
  width: 900px;
  margin: 16px 0 0;
  font: 8px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #8a8a8a;
}

/* ---- blog ---- */

/* blog pages keep the card exactly the lander's size so nothing moves
   going between them. the header stays put and everything under it
   scrolls inside the card (site.js sends the wheel there from anywhere) */
.long #card { display: flex; flex-direction: column; height: var(--card-h); }
.long #art { flex: none; height: 154px; }
#blog, #post, #comms { flex: 1; min-height: 0; overflow-y: auto; outline: none; }

#blog {
  display: flex;
  gap: 40px;
  padding: 16px 38px 28px;
}
#blog .main { flex: 1; min-width: 0; }
#blog .side { flex: none; width: 198px; }
.blurb { margin: 0 0 12px; color: #c8b6e6; }

.entry {
  display: block;
  padding: 12px 0 13px;
  border-top: 1px dotted rgba(225,205,255,.35);
}
.entry:hover { text-decoration: none; }
.entry .t { display: block; font: 14px/20px pix14, Verdana, sans-serif; color: #f5efff; }
.entry:hover .t { color: #fff; text-decoration: underline; }
.entry .d { display: block; color: #d9cdf0; }
.when {
  display: block;
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #ac8fe8;
}
.tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.tags i {
  padding: 0 6px;
  border: 1px solid rgba(225,205,255,.4);
  font: normal 8px/15px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
}

#cal .head {
  display: flex;
  justify-content: space-between;
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
}
#cal button {
  padding: 0 5px;
  border: 0;
  background: none;
  font: inherit;
  color: #ac8fe8;
  cursor: pointer;
}
#cal button:hover { color: #fff; }
#cal .grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  margin-top: 5px;
  text-align: center;
  font: 8px/21px Silkscreen, monospace;
  color: #9a86c2;
}
#cal .wd { color: #ac8fe8; }
#cal .out { opacity: .3; }
#cal .grid a {
  outline: 1px solid rgba(225,205,255,.6);
  background: rgba(199,166,255,.22);
  color: #fff;
}
#cal .grid a:hover { background: rgba(199,166,255,.45); text-decoration: none; }

/* post page */
#progress {
  position: fixed;
  z-index: 10;
  top: 0; left: 0;
  width: 100%; height: 2px;
  background: #c7a6ff;
  box-shadow: 0 0 6px #a67cff;
  /* stretched with a transform rather than a width so scrolling doesnt
     redo layout every frame */
  transform: scaleX(0);
  transform-origin: 0 0;
}
#post { padding: 16px 38px 33px; }
.back {
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #ac8fe8;
}
.ptitle {
  margin: 9px 0 2px;
  font: normal 24px pix24, Verdana, sans-serif;
  letter-spacing: 2px;
  color: #f7f1ff;
  text-shadow: 0 0 3px #dcc8ff, 0 0 8px #a67cff;
}
#post .d { margin: 9px 0 0; color: #d9cdf0; }
.stats i { color: #f5efff; border-color: rgba(225,205,255,.6); background: rgba(199,166,255,.15); }

.toc {
  margin: 16px 0 5px;
  padding: 2px 12px;
  border: 1px solid rgba(225,205,255,.35);
}
.toc summary {
  font: 8px/23px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
  cursor: pointer;
}
.toc ol { margin: 2px 0 9px; padding-left: 23px; }
.toc li.h3 { margin-left: 16px; list-style: circle; }

.prose { font: 14px/23px pix14, Verdana, sans-serif; color: #ece4fb; }
.prose p { margin: 14px 0; }
.prose a { text-decoration: underline; }
/* each section starts on a hairline, like the old blog's dividers */
.prose h2 {
  margin: 30px 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(225,205,255,.3);
  font: normal 18px pix18, Verdana, sans-serif;
  letter-spacing: 1px;
  color: #f7f1ff;
  text-shadow: 0 0 6px #a67cff;
}
.prose h3 {
  margin: 18px 0 -7px;
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
}
.prose ul, .prose ol { padding-left: 23px; }
.prose blockquote {
  margin: 14px 0;
  padding: 2px 14px;
  border-left: 2px solid #ac8fe8;
  font-style: italic;
  color: #d9cdf0;
}
.prose code { padding: 0 3px; background: rgba(10,0,30,.35); font: 13px pixgothic13, "MS Gothic", monospace; }
.prose pre {
  overflow-x: auto;
  padding: 9px 12px;
  border: 1px solid rgba(225,205,255,.25);
  background: rgba(10,0,30,.45);
  font: 13px/19px pixgothic13, "MS Gothic", monospace;
}

.gallery { margin: 16px 0; border: 1px solid rgba(225,205,255,.35); }
.ghead {
  display: flex;
  justify-content: space-between;
  padding: 0 9px;
  border-bottom: 1px solid rgba(225,205,255,.25);
  font: 8px/23px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
}
.gallery .view { position: relative; aspect-ratio: 1520 / 500; background: center / cover; }
.gallery .view::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(transparent 0 2px, rgba(20,0,40,.3) 2px 3px);
}
.gallery .cap { padding: 5px 9px 7px; font: 13px/20px pix13, Verdana, sans-serif; color: #d9cdf0; }
.gallery .strip { display: flex; gap: 5px; padding: 0 9px 9px; }
.gallery .strip button {
  width: 76px; height: 25px;
  padding: 0;
  border: 1px solid transparent;
  background: center / cover;
  opacity: .5;
  cursor: pointer;
}
.gallery .strip button:hover { opacity: .8; }
.gallery .strip button.on { opacity: 1; border-color: #c7a6ff; }

/* ---- commissions ---- */

/* the content keeps clear of me standing on the right */
#comms { padding: 16px 38px 28px; margin-right: 285px; }
/* me, stood at the right of the card with her feet off the bottom edge.
   not inside the scrolling, so she stays put. tinted like the art strip */
#me {
  position: absolute;
  z-index: 2;
  right: max(0px, calc((100% - 900px) / 2));
  bottom: 0;
  width: auto;
  height: 470px;
  filter: drop-shadow(3px 4px 0 rgba(26, 8, 48, .55));
  pointer-events: none;
}
#comms .k {
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #ac8fe8;
}

.tiers { display: flex; gap: 6px; margin: 4px 0 12px; }
.tiers button {
  flex: 1;
  padding: 5px 9px 6px;
  border: 1px solid rgba(225,205,255,.4);
  background: rgba(10,0,30,.25);
  text-align: left;
  font: 13px/20px pix13, Verdana, sans-serif;
  color: #d9cdf0;
  cursor: pointer;
}
.tiers button b { display: block; font: normal 8px/14px Silkscreen, monospace; letter-spacing: 1px; color: #ac8fe8; }
.tiers button:hover { border-color: #c7a6ff; color: #fff; }
.tiers button.on { border-color: #c7a6ff; background: rgba(199,166,255,.22); color: #fff; }
.tiers button.on b { color: #e4d6ff; }

#tier { padding-bottom: 6px; }
#tier .what { margin: 0; color: #d9cdf0; }
.slot { display: inline-block; width: 5px; height: 5px; margin-left: 2px; border: 1px solid #c7a6ff; vertical-align: 0; }
.slot.gone { background: #c7a6ff; }
.opts { margin: 10px 0 0; }
.opt { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0 0 6px; }
.opt .k { width: 128px; }
.chip {
  padding: 0 6px;
  border: 1px solid rgba(225,205,255,.4);
  background: none;
  font: 8px/15px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
  cursor: pointer;
}
.chip:hover { border-color: #c7a6ff; }
.chip.on { border-color: #c7a6ff; background: rgba(199,166,255,.3); color: #fff; }
.chip.step { width: 17px; padding: 0; }
.opt .n { min-width: 14px; text-align: center; }
.opt .each, .opt .note { font: 8px/15px Silkscreen, monospace; letter-spacing: 1px; color: #9a86c2; }
.opt .note { flex-basis: 100%; padding-left: 132px; }
.est { display: flex; align-items: baseline; gap: 12px; margin: 10px 0 8px; }
.est b {
  font: normal 24px pix24, Verdana, sans-serif;
  color: #f7f1ff;
  text-shadow: 0 0 3px #dcc8ff, 0 0 8px #a67cff;
}
.order {
  display: inline-block;
  margin-bottom: 14px;
  padding: 2px 10px;
  border: 1px solid #c7a6ff;
  background: rgba(199,166,255,.22);
  font: 8px/17px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #fff;
}
.order:hover { background: rgba(199,166,255,.45); text-decoration: none; }
.order.full { border-color: rgba(225,205,255,.4); background: none; color: #c7a6ff; }

/* example thumbs with the price in the corner, click opens #viewer */
.ex { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 18px; }
.ex button {
  position: relative;
  width: 104px; height: 104px;
  padding: 0;
  border: 1px solid rgba(225,205,255,.35);
  background: center / cover;
  cursor: zoom-in;
}
.ex button:hover { border-color: #c7a6ff; }
.ex button i {
  position: absolute;
  left: 0; top: 0;
  padding: 0 4px;
  background: #531fad;
  font: normal 8px/14px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #fff;
}

#terms { margin: 2px 0 10px; }
#terms details { border-top: 1px dotted rgba(225,205,255,.35); }
#terms details:last-child { border-bottom: 1px dotted rgba(225,205,255,.35); }
#terms summary {
  padding: 3px 0;
  font: 8px/20px Silkscreen, monospace;
  letter-spacing: 1px;
  color: #c7a6ff;
  cursor: pointer;
}
#terms summary:hover { color: #fff; }
#terms ul { margin: 0 0 8px; padding-left: 18px; color: #d9cdf0; }
#terms p { margin: 0 0 8px; color: #d9cdf0; }
#terms .k { margin-top: 2px; }
.kofi { margin: 0 0 4px; }
.kofi a { font: 8px/20px Silkscreen, monospace; letter-spacing: 1px; color: #c7a6ff; }

/* big example over the whole screen */
#viewer {
  position: fixed;
  z-index: 30;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(7, 5, 10, .9);
  cursor: zoom-out;
}
#viewer[hidden] { display: none; }
#viewer img {
  max-width: 92%;
  max-height: calc(var(--fit-h, 100vh) * .84);
  border: 1px solid #c7a6ff;
  box-shadow: 0 0 16px #6d3fc0;
}
#viewer p { margin: 10px 0 0; font: 8px Silkscreen, monospace; letter-spacing: 1px; color: #c7a6ff; }

/* phones held upright (fit() sets .tall): the card goes right to the edges
   of the screen, info stacked */
.tall { --card-h: 560px; }
.tall #copy { align-self: stretch; width: auto; padding: 0 20px; }
/* the strip already reaches the card's sides here, no side fade */
.tall #art { height: 190px; --side-fade: linear-gradient(#000, #000); }
.tall h1 {
  margin-top: -56px;
  padding: 26px 16px 9px;
  font: normal 30px pix30, Verdana, sans-serif;
  letter-spacing: 4px;
}
.tall hr { margin: 6px 20px 0; }
.tall #tabs { margin: 10px 12px 0; padding: 0 6px; }
.tall #tabs a + a::before { margin: 0 5px; }
/* no room for the word on a phone, the envelope says it */
.tall #tabs #contact { font-size: 0; letter-spacing: 0; }
.tall #about { display: block; padding: 14px 20px 20px; }
.tall #about .me { width: auto; }
.tall #about .social { width: auto; margin-top: 14px; }
.tall.long #art { height: 110px; }
.tall #blog { display: block; padding: 14px 20px 20px; }
.tall #blog .side { width: auto; margin-top: 18px; }
.tall #post { padding: 14px 20px 24px; }
/* on phones i stand in the corner of the scrolling bit with the text
   round me instead */
.tall #comms { padding: 14px 20px 20px; margin-right: 0; }
.tall #me { position: static; float: right; height: 210px; margin: -6px -10px 4px 6px; }
/* the kinds stack up beside me, the rest starts under my feet */
.tall .tiers { flex-direction: column; gap: 5px; }
.tall .tiers button { padding: 3px 8px 4px; }
.tall #tier { clear: both; }
.tall .opt .k { width: 100%; }
.tall .opt .note { padding-left: 0; }
.tall .ex button { width: 92px; height: 92px; }
.tall .gallery .strip button { width: 52px; height: 17px; }

/* live: just the lander (tools/deploy.py) */
html { --card-h: 496px; }
.tall { --card-h: 482px; }
