/* ==========================================================================
   styles.css  |  dark
   --------------------------------------------------------------------------
   One column, in the dark. A single typeface, warm off-white on near black,
   a visible grain over everything. Hierarchy from size and opacity only.

   Contents
     01 tokens
     02 base and grain
     03 the column
     04 intro
     05 tabs
     06 the car
     07 footer
     08 blog page
     09 responsive, print
   ========================================================================== */

/* 01 tokens ------------------------------------------------------------- */

:root {
  --bg: #060606;
  --fg: #ecebe7;
  --fg-2: hsl(40 10% 92% / 0.62);
  --fg-3: hsl(40 10% 92% / 0.38);
  --rule: hsl(40 10% 92% / 0.13);

  --font: "Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;

  --col: 700px;
  --pad: clamp(1.5rem, 5vw, 2.5rem);
}

/* 02 base and grain ----------------------------------------------------- */

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

html, body { height: 100%; }

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
}

p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }

::selection { background: var(--fg); color: var(--bg); }

.skip {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 100;
  padding: 0.6em 1em;
  background: var(--fg);
  color: var(--bg);
  font-size: 0.75rem;
}

.skip:focus { left: 0; }

:focus-visible { outline: 1.5px solid var(--fg); outline-offset: 3px; }

/* 03 the column --------------------------------------------------------- */

.page {
  position: relative;
  z-index: 1;
  width: min(100% - 2 * var(--pad), var(--col));
  margin-inline: auto;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(0.9rem, 2.2vh, 1.4rem);
  padding-block: clamp(1.5rem, 5vh, 3rem) clamp(0.5rem, 1.5vh, 0.9rem);
}

.foot {
  position: relative;
  z-index: 1;
  width: min(100% - 2 * var(--pad), var(--col));
  margin-inline: auto;
  padding-block: 0.9rem clamp(0.9rem, 3.5vh, 2rem);
  font-size: 0.78rem;
  color: var(--fg-3);
}

/* 04 intro -------------------------------------------------------------- */

.intro__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.45em 0.9em;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: none;
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--fg-2);
  text-decoration: none;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}

.btn:hover {
  color: var(--fg);
  border-color: var(--fg-3);
  background: hsl(40 10% 92% / 0.04);
}

.btn--solid {
  color: var(--bg);
  background: var(--fg);
  border-color: var(--fg);
}

.btn--solid:hover {
  color: var(--bg);
  background: #fff;
  border-color: #fff;
}

.btn svg { width: 12px; height: 12px; }

.btn svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.name {
  margin: 0;
  font-weight: 500;
  font-size: clamp(1.8rem, 1.2rem + 2vw, 2.6rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.role {
  margin-top: 0.4rem;
  font-size: 0.85rem;
  color: var(--fg-3);
}

.bio {
  max-width: 54ch;
  margin-top: 1rem;
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--fg-2);
}

/* 05 tabs --------------------------------------------------------------- */

.tabs {
  display: flex;
  gap: 1.6rem;
  border-bottom: 1px solid var(--rule);
}

.tab {
  position: relative;
  padding: 0 0 0.55rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.84rem;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  cursor: pointer;
  transition: color 0.18s ease;
}

.tab:hover { color: var(--fg-2); }
.tab.is-active { color: var(--fg); }

.tab.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--fg);
}

/* the link out to the blog, sitting with the tabs */
.tab--link {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--fg-2);
  text-decoration: none;
  transition: color 0.18s ease;
}

.tab--link:hover { color: var(--fg); }
.tab--link:hover::after { width: 100%; }

.tab--link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 1px;
  width: 0;
  background: var(--fg);
  transition: width 0.25s ease;
}

.tab--link svg {
  width: 10px;
  height: 10px;
}

.tab--link svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.panels {
  min-height: 214px;
  max-height: 288px;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* keep the rows clear of the scrollbar, without shifting them off the
     alignment of the tabs and links above */
  margin-right: -0.85rem;
  padding-right: 0.85rem;
}

/* a visible scrollbar, so it is obvious there is more to scroll */
.panels::-webkit-scrollbar { width: 6px; }
.panels::-webkit-scrollbar-track {
  background: hsl(40 10% 92% / 0.05);
  border-radius: 3px;
}
.panels::-webkit-scrollbar-thumb {
  background: hsl(40 10% 92% / 0.3);
  border-radius: 3px;
}
.panels::-webkit-scrollbar-thumb:hover { background: hsl(40 10% 92% / 0.45); }

.panel { display: none; }
.panel.is-active { display: block; }

.player {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
}

/* Spotify draws a rounded card on a white page. We clip the iframe with our
   own rounded frame and bleed it a couple of pixels, so the white corners
   are cropped away instead of showing. */
.player__frame {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: #121212;
}

/* Spotify leaves a hairline of white along the bottom edge. Crop it away
   instead of covering it, so the rounded corners survive. */
.player__frame iframe {
  display: block;
  width: calc(100% + 3px);
  height: calc(100% + 12px);
  margin: -1px -1.5px -11px;
  border: 0;
  background: #121212;
  color-scheme: dark;
}

/* and a two pixel belt, in case the hairline moves with zoom */
.player__frame::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: #121212;
  pointer-events: none;
}

.player--empty {
  display: grid;
  place-items: center;
  height: 152px;
  border: 1px dashed var(--rule);
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
}

.group + .group { margin-top: 0.85rem; }

.label {
  margin-bottom: 0.1rem;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-3);
}

.row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.22rem 0;
  text-decoration: none;
}

.row__name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 0.9rem;
  color: hsl(40 10% 92% / 0.86);
  transition: color 0.18s ease;
}

.row__name em {
  font-style: normal;
  margin-left: 0.55rem;
  font-size: 0.81rem;
  color: var(--fg-3);
}

.row__year {
  flex: 0 0 auto;
  font-size: 0.78rem;
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}

a.row:hover .row__name,
a.row:hover .row__year { color: var(--fg); }

/* anything that is a link reads as a link, but the quiet note stays plain */
a.row .row__label {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--fg-3);
}

a.row:hover .row__label { text-decoration-color: var(--fg); }

/* 06 links and the car -------------------------------------------------- */

.links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.6rem;
}

.links a {
  font-size: 0.86rem;
  color: var(--fg-2);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: var(--fg-3);
  transition: color 0.18s ease, text-decoration-color 0.18s ease;
}

.links a:hover {
  color: var(--fg);
  text-decoration-color: var(--fg-3);
}

.car {
  position: relative;
  flex: 0 0 auto;
  height: clamp(160px, 19vh, 210px);
  margin-top: auto;
}

.car canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: block;
  cursor: pointer;
  touch-action: none;
}

.car__fallback {
  display: none;
  position: absolute;
  inset: 0;
  place-items: center;
  text-align: center;
  font-size: 0.76rem;
  color: var(--fg-3);
}

.no-3d .car__fallback,
.is-file .car__fallback { display: grid; }

.no-3d .car canvas,
.is-file .car canvas { display: none; }

.car__keys {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--fg-3);
  pointer-events: none;
}

.car__keys svg { width: 12px; height: 12px; }

.car__keys svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.car__hud {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  gap: 1.1rem;
  font-size: 0.72rem;
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.car__hud b { font-weight: 500; color: var(--fg); }

/* step through the cars by hand, one arrow each side */
.car__arrow {
  position: absolute;
  top: 50%;
  z-index: 2;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--fg-3);
  cursor: pointer;
  transition: color 0.18s ease;
}

.car__arrow--prev { left: -4px; }
.car__arrow--next { right: -4px; }

.car__arrow:hover { color: var(--fg); }
.car__arrow svg { width: 8px; height: 13px; }

.car__arrow svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.no-3d .car__arrow,
.is-file .car__arrow { display: none; }

/* 07 blog page ---------------------------------------------------------- */

body.doc {
  display: block;
  height: auto;
  min-height: 100svh;
  overflow: auto;
}

.blog {
  position: relative;
  z-index: 1;
  width: min(100% - 2 * var(--pad), var(--col));
  margin-inline: auto;
  padding-block: clamp(2rem, 7vh, 4rem) clamp(3rem, 8vh, 5rem);
}

.blog__title {
  margin-top: 1.6rem;
  font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.2rem);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.blog__note {
  margin-top: 0.4rem;
  font-size: 0.9rem;
  color: var(--fg-3);
}

.blog__list { margin-top: 2rem; }
.blog__list li:last-child .post { border-bottom: 1px solid var(--rule); }

/* the categories, and the pages */
.blog__cats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.2rem;
  margin-top: 1.4rem;
}

.blog__cats:empty { display: none; }

.blog__cats a {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  text-decoration: none;
  transition: color 0.18s ease;
}

.blog__cats a:hover { color: var(--fg-2); }

.blog__cats a.is-active {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.blog__pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.6rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
  font-size: 0.78rem;
}

.blog__pager:empty { display: none; }

.blog__pager a {
  color: var(--fg-3);
  text-decoration: none;
  transition: color 0.18s ease;
}

.blog__pager a:hover { color: var(--fg); }
.blog__pager a.is-active { color: var(--fg); }
.blog__pager .is-off { color: hsl(40 10% 92% / 0.16); }
.blog__nums { display: flex; gap: 0.85rem; }

.post {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.05rem 0;
  border-top: 1px solid var(--rule);
  text-decoration: none;
}

.post__thumb {
  flex: 0 0 104px;
  height: 68px;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background-size: cover;
  background-position: center;
}

.post__text { min-width: 0; }

.post__cover {
  width: 100%;
  margin-bottom: 1.4rem;
  border-radius: 2px;
}

.post__date {
  display: block;
  font-size: 0.72rem;
  color: var(--fg-3);
}

.post__title {
  display: block;
  margin-top: 0.25rem;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--fg);
}

.post__excerpt {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--fg-2);
}

a.post:hover .post__title {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* a single post, rendered from markdown */
.blog__meta {
  margin-top: 0.4rem;
  font-size: 0.78rem;
  color: var(--fg-3);
}

.blog__meta a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.18s ease;
}

.blog__meta a:hover { color: var(--fg); }

.prose {
  margin-top: 1.6rem;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--fg-2);
}

.prose h2 {
  margin: 2.1rem 0 0.6rem;
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.prose h3 {
  margin: 1.7rem 0 0.5rem;
  font-size: 1.08rem;
  font-weight: 500;
  color: var(--fg);
}

.prose p { margin: 0.9rem 0; }

/* display maths, rendered by KaTeX. it may be wider than the column */
.prose .math {
  margin: 1.2rem 0;
  overflow-x: auto;
  overflow-y: hidden;
}

.prose .math .katex-display { margin: 0; }

/* tables, with the same hairline rules as the rest of the page */
.prose table {
  width: 100%;
  margin: 1.3rem 0;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.prose th,
.prose td {
  padding: 0.42rem 0.7rem;
  border-bottom: 1px solid var(--rule);
  text-align: left;
}

.prose th:first-child,
.prose td:first-child { padding-left: 0; }
.prose th:last-child,
.prose td:last-child { padding-right: 0; }

.prose thead th {
  border-bottom-color: var(--fg-3);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-3);
}

.prose tbody td {
  font-size: 0.94rem;
  color: var(--fg-2);
}
.prose ul, .prose ol { margin: 0.9rem 0; padding-left: 1.3rem; }
.prose li { margin: 0.3rem 0; }

/* the site strips markers off its own lists, so put them back for prose */
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose ul ul { list-style: circle; }
.prose ul ul ul { list-style: square; }
.prose li::marker { color: var(--fg-3); }

.prose a {
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.prose strong { color: var(--fg); font-weight: 600; }

.prose code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 0.86em;
  background: hsl(40 10% 92% / 0.07);
  padding: 0.12em 0.35em;
  border-radius: 2px;
}

.prose pre {
  margin: 1.1rem 0;
  padding: 0.9rem 1rem;
  background: hsl(40 10% 92% / 0.05);
  border: 1px solid var(--rule);
  border-radius: 2px;
  overflow-x: auto;
}

.prose pre code {
  background: none;
  padding: 0;
  font-size: 0.84rem;
}

.prose blockquote {
  margin: 1.2rem 0;
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
  color: var(--fg-3);
}

.prose hr {
  margin: 2rem 0;
  border: 0;
  border-top: 1px solid var(--rule);
}

/* 08 responsive, print -------------------------------------------------- */

@media (max-width: 700px) {
  body { overflow: auto; }

  .panels { min-height: 0; }

  .car { height: 200px; }

  .tabs { gap: 1.2rem; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

@media print {
  body { height: auto; overflow: visible; }
  body::before, .car, .tabs { display: none; }
  .panel { display: block; }
}
