
/* Latin subset: no box-drawing glyphs, so all chrome is CSS. */
@font-face {
  font-family: "Fira Code";
  src: url("/fonts/FiraCode-Latin-VF.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #101016;
  --cream: #efe6d5;
  --berry: #e04a54;
  --leaf: #8aa970;
  --dim: #9a8f80;
  --yellow: #f2d98c;
  --line: #2f2f3a;
  --measure: 76ch;
}

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

html {
  background: var(--bg);
  color: var(--cream);
  font-family: "Fira Code", ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 15px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  padding: 1.5rem 1rem;
  display: flex;
  justify-content: center;
  overflow: hidden;
}

.win {
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  height: 100%;
  max-width: var(--measure);
  min-height: 0;
  width: 100%;
}

.titlebar, .status { flex: 0 0 auto; }

.titlebar {
  background: var(--berry);
  color: var(--bg);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.1rem 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.titlebar .right { font-weight: 400; opacity: 0.85; }

.session {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0.8rem 1.5ch 1rem;

  scrollbar-width: thin;
  scrollbar-color: var(--leaf) transparent;
}

.session::-webkit-scrollbar { width: 10px; }
.session::-webkit-scrollbar-track { background: transparent; }
.session::-webkit-scrollbar-thumb { background: var(--leaf); border: 0; }
.session::-webkit-scrollbar-thumb:hover { background: var(--cream); }

.ps1 {
  margin: 1.5rem 0 0.35rem;
  color: var(--cream);
  overflow-wrap: anywhere;
  letter-spacing: 0.06em;
}

.ps1::before {
  content: "guest@actulily:~$";
  color: var(--leaf);
  margin-right: 1ch;
  letter-spacing: 0;
}
.ps1:first-child { margin-top: 0; }
.run { color: var(--cream); }

.boot {
  color: var(--leaf);
  font: inherit;
  letter-spacing: 0.06em;
  margin: 0 0 1.2rem;
  white-space: pre-wrap;
  text-align: center;
}

.boot .lead { color: var(--line); }
.boot .ok { color: var(--leaf); }
.boot .bl { display: block; }

.boot .bl.gap { margin-bottom: 1.15em; }

.out { margin: 0; }

.err {
  color: var(--berry);
  font: inherit;
  letter-spacing: 0.06em;
  margin: 0 0 0.4rem;
  white-space: pre-wrap;
}

.note { color: var(--dim); letter-spacing: 0.06em; }

.live, .entry { margin-bottom: 1.6rem; }

/* Blinks under reduced motion on purpose: it stands in for the native caret. */
.cursor {
  animation: blink 1.5s steps(1, end) infinite;
  background: var(--dim);
  display: inline-block;
  height: 1.05em;
  vertical-align: -0.2em;
  width: 0.62em;
}

@keyframes blink { 0%, 45% { opacity: 1; } 45.01%, 100% { opacity: 0; } }

.sr-title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

h1 { font-size: 1.375rem; font-weight: 700; line-height: 1.25; margin: 0 0 0.1rem; }
h2 { font-size: 1rem; font-weight: 600; margin: 0; letter-spacing: 0.06em; }

a { color: var(--cream); text-decoration: underline; text-underline-offset: 2px; }
a:hover, a:focus-visible {
  background: var(--berry);
  color: var(--bg);
  text-decoration: none;
  outline: none;
}

.splash { display: flex; justify-content: center; padding: 0.5rem 0 0.6rem; }
.mark img { display: block; width: 96px; height: 96px; }

.hero { margin-bottom: 0.2rem; }

.handle { color: var(--berry); margin: 0 0 0.35rem; }
.intro { color: var(--dim); margin: 0; }

.rows, .projects, .contact, .posts { list-style: none; margin: 0; padding: 0; }

.rows li, .contact li, .posts li { display: flex; gap: 2ch; }
.rows .when, .posts .when { color: var(--dim); flex: 0 0 13ch; }
.contact .key { color: var(--dim); flex: 0 0 10ch; }
.rows .what, .posts a { flex: 1; }
.contact a { display: inline-flex; align-items: center; gap: 0.7ch; }

.rows li, .posts li, .contact li { padding: 0 1ch; margin: 0 -1ch; }
.rows li:hover, .posts li:hover, .contact li:hover { background: #1b1b24; }

.projects li { margin-bottom: 0.85rem; }
.projects li:last-child { margin-bottom: 0; }

.projects .head {
  display: flex;
  align-items: baseline;
  gap: 1ch;
  margin-bottom: 0.2rem;
}

.projects .head .visit { margin-right: auto; }

.projects h2 { color: var(--berry); }

.projects p { margin: 0; max-width: 68ch; }

.visit { color: var(--berry); display: inline-flex; text-decoration: none; font-size: 0.8em; }
.visit:hover, .visit:focus-visible { background: none; color: var(--cream); }

.prose p { max-width: 68ch; }
.prose a { color: var(--cream); }
.prose .meta { color: var(--dim); margin: 0 0 0.2rem; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.ico {
  width: 1.15em;
  height: 1.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
  flex: 0 0 auto;
  transform: translateY(0.09em);
}

.status {
  border-top: 1px solid var(--line);
  color: var(--dim);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 0 1.5rem;
  padding: 0.3rem 0.75rem;
  font-size: 0.875rem;
}

.status span:nth-child(2) { text-align: center; }
.status span:nth-child(3) { text-align: right; }
.status b { color: var(--cream); font-weight: 600; }

.place { display: inline-flex; align-items: center; gap: 0.7ch; cursor: default; }

.bunny {
  display: inline-block;
  width: 1.1em;
  height: 1.2em;
  overflow: hidden;
  vertical-align: -0.22em;
}

.bunny-strip { display: flex; width: 300%; height: 100%; }

.bunny-frame {
  flex: 0 0 33.3333%;
  width: 33.3333%;
  height: 100%;
  fill: currentColor;
  fill-rule: evenodd;

  stroke: currentColor;
  stroke-width: 0.9;
  stroke-linejoin: round;
}

.place:hover .bunny-strip { animation: hop-frames 0.66s steps(3, end); }
.place:hover .bunny { animation: hop-arc 0.66s ease-in-out; }

.place.hop2 .bunny-strip { animation: hop-frames 0.66s steps(3, end) 2; }
.place.hop2 .bunny { animation: hop-arc 0.66s ease-in-out 2; }

@keyframes hop-frames { to { transform: translateX(-100%); } }

@keyframes hop-arc {
  0%, 33% { transform: translateY(0); }
  50% { transform: translateY(-0.5em); }
  67%, 100% { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .place:hover .bunny, .place.hop2 .bunny,
  .place:hover .bunny-strip, .place.hop2 .bunny-strip { animation: none; }
}

@media (max-width: 38rem) {
  .rows li, .posts li, .work li, .contact li { display: block; }
  .rows .when, .posts .when, .work .key, .contact .key { display: block; color: var(--dim); }
  .work li { margin-bottom: 0.8rem; }
  .titlebar .right { display: none; }
}

/* !important: .cmds{display:flex} has equal specificity and is declared later. */
.pending { display: none !important; }

.veiled { visibility: hidden; }

.entry.busy { visibility: hidden; }

/* Holds the session invisible until term.js loads, or it paints and is yanked away. */
.js:not(.termready) .session > *:not(.splash),
.js:not(.termready) .cmds { visibility: hidden; }

.hint { color: var(--dim); margin-top: 1rem; }

.entry { position: relative; cursor: text; }

.term-input {
  background: none;
  border: 0;
  bottom: 0;
  caret-color: transparent;
  color: transparent;
  font: inherit;
  left: 0;
  outline: none;
  padding: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: 100%;
}

.entry .cursor { position: relative; }

.typed { color: var(--cream); letter-spacing: 0.06em; white-space: pre-wrap; }

.reply {
  color: var(--dim);
  font: inherit;
  margin: 0 0 0.2rem;
  white-space: pre-wrap;
}

.replayed { margin-bottom: 0.2rem; }

.mark.spin { animation: markspin 0.6s ease-in-out; }
@keyframes markspin { to { transform: rotate(360deg); } }

.place.hopping .bunny-strip { animation: hop-frames 0.66s steps(3, end); }
.place.hopping .bunny { animation: hop-arc 0.66s ease-in-out; }

@media (prefers-reduced-motion: reduce) {
  .place.hopping .bunny-strip, .place.hopping .bunny { animation: none; }
  .mark.spin { animation: none; }
}

.cmds {
  border-bottom: 1px solid var(--line);
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  gap: 0.15rem 2.5ch;
  justify-content: center;
  padding: 0.3rem 1.5ch;
}

.cmds a, .cmds button { color: var(--dim); text-decoration: none; }
.cmds a b, .cmds button b { color: var(--berry); font-weight: 400; }
.cmds a:hover, .cmds a:focus-visible,
.cmds button:hover, .cmds button:focus-visible { background: var(--berry); color: var(--bg); outline: none; }
.cmds a:hover b, .cmds a:focus-visible b,
.cmds button:hover b, .cmds button:focus-visible b { color: var(--bg); }

.flags { display: flex; gap: 2ch; margin-bottom: 0.6rem; }

.flag {
  aspect-ratio: 3 / 2;
  display: flex;
  flex-direction: column;
  width: 9ch;
}

.flag i { display: block; flex: 1 1 0; }

.rainbow i:nth-child(1) { background: #e40303; }
.rainbow i:nth-child(2) { background: #ff8c00; }
.rainbow i:nth-child(3) { background: #ffed00; }
.rainbow i:nth-child(4) { background: #008026; }
.rainbow i:nth-child(5) { background: #24408e; }
.rainbow i:nth-child(6) { background: #732982; }

.trans i:nth-child(1), .trans i:nth-child(5) { background: #5bcefa; }
.trans i:nth-child(2), .trans i:nth-child(4) { background: #f5a9b8; }
.trans i:nth-child(3) { background: #ffffff; }

.roles { list-style: none; margin: 0; padding: 0; }
.roles > li { margin-bottom: 0.75rem; }
.roles > li:last-child { margin-bottom: 0; }
.roles .head { display: flex; gap: 2ch; }
.roles .when { color: var(--dim); flex: 0 0 13ch; }
.roles .bullets { list-style: none; margin: 0.15rem 0 0; padding: 0 0 0 15ch; }
.roles .bullets li { max-width: 62ch; text-indent: -2ch; padding-left: 2ch; }
.roles .bullets li::before { content: "- "; color: var(--dim); }

@media (max-width: 38rem) {
  .roles .head { display: block; }
  .roles .when { display: block; }
  .roles .bullets { padding-left: 0; }

  /* Three centered lines. Direct children only — a descendant selector also
     catches the year span and the bunny's sprite spans, which breaks both.
     The nth-child rules above are (0,2,1), so these must match to win. */
  .status { display: block; line-height: 1.7; }
  .status > span { display: block; }
  .status > span:nth-child(1),
  .status > span:nth-child(2),
  .status > span:nth-child(3) { text-align: center; }

  /* Stays a flex row, or the rabbit loses its gap and baseline. */
  .status > .place { display: flex; justify-content: center; }
}

.reply a[data-run] { color: var(--berry); text-decoration: none; }
.reply a[data-run]:hover, .reply a[data-run]:focus-visible {
  background: var(--berry);
  color: var(--bg);
}

.entry.in-adventure::before,
.ps1.adv::before { content: "adventure>"; color: var(--berry); }

.reply button[data-run] {
  background: none;
  border: 0;
  color: var(--berry);
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  padding: 0;
}

.reply button[data-run]:hover,
.reply button[data-run]:focus-visible { background: var(--berry); color: var(--bg); outline: none; }

.cmds .runcmd { display: none; }
.js .cmds .runcmd { display: inline; }

.cmds button {
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  padding: 0;
}

/* Not .entry: that is the live prompt, and the two shared a margin. */
.post { margin-bottom: 1.4rem; }
.post:last-of-type { margin-bottom: 0.4rem; }
.post h2 { color: var(--berry); margin-bottom: 0.1rem; }
.post h2 a { color: inherit; text-decoration: none; }
.post h2 a:hover, .post h2 a:focus-visible { background: var(--berry); color: var(--bg); }
.post .meta { color: var(--dim); margin: 0; }

.yr { color: var(--dim); cursor: default; outline: none; }

/* blue, white, pink, white: ending on a different colour than it starts is what
   hides the seam. background-size is exactly one tile, and the animation travels
   exactly one tile, so the loop is continuous. */
.yr:hover, .yr:focus-visible {
  animation: flagwipe 2.6s linear infinite;
  background-clip: text;
  -webkit-background-clip: text;
  background-image: linear-gradient(
    90deg,
    #5bcefa 0 25%, #ffffff 25% 50%, #f5a9b8 50% 75%, #ffffff 75% 100%
  );
  background-size: 2em 100%;
  color: transparent;
}

@keyframes flagwipe { to { background-position: 2em 0; } }

@media (prefers-reduced-motion: reduce) {

  .yr:hover, .yr:focus-visible { animation: none; }
}

.unrendered { display: none; }

.cta { margin-top: 0.7rem; }
.cta a { color: var(--berry); }
