/* There is no webfont here and there will not be one. The CSP is default-src 'self', so a
   typeface from Google or a CDN costs a widened font-src on every page for ever, and the
   policy is worth more than the typeface. */

:root {
  /* Dark academia. Every value below is lifted from the reference palette rather than
     mixed towards it, so the scheme stays a scheme and does not drift into approximation. */
  color-scheme: dark;

  --bg: #1a2328;
  --fg: #caaf9c;
  --secondary: #baac91;
  --muted: #927e5d;
  --accent: #d4a152;
  --rule: #393941;
}

/* min-height is the viewport and body carries 4rem of padding. Under the default content-box
   that padding is added to the viewport height rather than counted inside it, and every page
   scrolls by exactly its own padding — a scrollbar with nothing behind it. */
*, *::before, *::after { box-sizing: border-box; }

html { background: var(--bg); }

/* The tiling sits behind everything and is never a target: it takes no clicks, no focus and
   no screen reader. Fixed rather than absolute so it does not scroll on a short viewport. */
/* The background picker. Fixed, so it stays out of the centred card's flow, and quiet enough
   that it reads as an affordance rather than as navigation.
   
   Hidden for now: one background is on show and a picker with a single entry is furniture.
   The markup and the modules are all still there, and ?bg=<name> still reaches any of them. */
.picker {
  display: flex;
  gap: 1.1rem;
  left: 50%;
  position: fixed;
  top: 1.1rem;
  transform: translateX(-50%);
  z-index: 1;
}

.picker button {
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  line-height: 0;
  opacity: 0.45;
  padding: 0.3rem;
  transition: color 140ms ease, opacity 140ms ease;
}

.picker button:hover, .picker button:focus-visible { color: var(--accent); opacity: 1; }
.picker button[aria-current="true"] { color: var(--accent); opacity: 1; }

.picker button:focus-visible { border-radius: 4px; outline: 2px solid currentColor; outline-offset: 3px; }

.picker svg {
  fill: none;
  height: 22px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.3;
  width: 22px;
}

/* Delete this rule to bring the picker back. It sits after the block above rather than inside
   it because a later declaration wins: display:none written first is simply overridden by the
   display:flex that follows it. */
.picker { display: none; }

#bg {
  height: 100%;
  inset: 0;
  pointer-events: none;
  position: fixed;
  width: 100%;
  z-index: -1;
}

body {
  /* Transparent, not --bg. The canvas behind this is a z-index:-1 child of body, which paints
     after the root background but before body's own — so a background here covers it exactly
     within the 34rem column. html carries the colour instead, for 404.html and for any page
     the script does not run on. */
  background: transparent;
  color: var(--fg);
  font: 17px/1.6 ui-serif, Georgia, "Times New Roman", serif;
  margin: 0 auto;
  max-width: 34rem;
  padding: 4rem 16px;
}

h1 { font-size: 1.6rem; font-weight: 600; letter-spacing: -0.01em; margin: 0 0 0.7rem; }

/* --muted is 4.08:1 against the ground, which is enough for an icon and short of the 4.5:1 a
   line of text wants. The roles sit one palette step brighter, at 7.15:1. */
.roles {
  color: var(--secondary);
  font-size: 0.95rem;
  margin: 0 0 2.25rem;
  text-wrap: balance;
}

/* Each role is unbreakable, and each bar carries its own leading non-breaking space, so a
   wrap falls only between roles — never inside "Software Engineer". Keeping the space inside
   the separator also means hiding the separator leaves no stray text node behind. */
.roles .role { white-space: nowrap; }
.roles .sep { opacity: 0.45; padding-right: 0.15em; }

/* Only index.html is a card. 404.html is a page of prose and stays where it is. */
.card {
  align-items: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  text-align: center;
}

.links { display: flex; gap: 1.75rem; }

.links a { color: var(--muted); display: block; transition: color 120ms ease; }
.links a:hover, .links a:focus-visible { color: var(--accent); }

.links a:focus-visible {
  border-radius: 4px;
  outline: 2px solid currentColor;
  outline-offset: 6px;
}

/* Stroked, so one width reads the same across all three. The fill is the letterform dot in
   the LinkedIn mark and is set on that element alone. */
.links svg {
  fill: none;
  height: 26px;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
  width: 26px;
}

a {
  color: inherit;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.15em;
}

a:hover { text-decoration-color: currentColor; }

/* 404.html, which is the only other page. */
hr { border: 0; border-top: 1px solid var(--rule); margin: 2rem 0; }
footer { color: var(--muted); font-size: 0.85rem; }
footer a { color: inherit; }

/* Wrapping the roles strands a bar at the end of the first line, so below this they stack
   instead, which reads as a title block rather than an accident. The separators go with the
   line they separated.

   The threshold is where the column reaches its full width, not where the roles stop
   fitting. They measure 28.5em in Georgia, 29.7em in New York, which is what Safari takes
   ui-serif to mean, and 31em in Noto Serif, the fallback on Android. A breakpoint of 30rem
   was set against Georgia, and phones in the other two passed it while still too narrow for
   one line. At its full width the column holds even Noto Serif with room over. */
@media (max-width: 34rem) {
  .roles { display: flex; flex-direction: column; gap: 0.1rem; }
  .roles .sep { display: none; }
}

@media (max-width: 36rem) {
  body { padding: 2.5rem 16px; }
}
