/* =========================================================
   michaelttsai.com
   One stylesheet. No framework, no build step, no dependencies.

   Contents
     1.  Design tokens
     2.  Base + light reset
     3.  Layout
     4.  Masthead + nav
     5.  Prose (the reading column)
     6.  Entry lists (projects + blog)
     7.  Status labels
     8.  Annotation block
     9.  Related links
     10. Footer
     11. Accessibility helpers
   ========================================================= */


/* ---------------------------------------------------------
   1. DESIGN TOKENS

   These are CSS custom properties: named values you define
   once and reuse everywhere. Change --accent here and every
   green on the site changes at once. This is why you almost
   never hardcode a colour further down the file.

   The name is the interface. --ink and --paper describe the
   ROLE the colour plays, not what it looks like, which means
   dark mode below can swap the values without renaming
   anything.
   --------------------------------------------------------- */
:root {
  /* colour */
  --paper:       #f6f6f4;
  --paper-2:     #ecece9;
  --ink:         #17181a;
  --ink-soft:    #6a6c68;
  --rule:        #dfe0da;
  --accent:      #1f5b41;
  --accent-soft: #e4efe9;

  /* type */
  --serif: Charter, "Bitstream Charter", "Sitka Text", Cambria, Georgia, serif;
  --mono:  ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
           "Liberation Mono", monospace;

  /* type scale. Fixed steps beat guessing a new size each time. */
  --micro:  0.78rem;
  --step-0: 1.0625rem;
  --step-1: 1.25rem;
  --step-2: 1.5rem;
  --step-3: 2rem;

  /* layout */
  --measure: 36rem;   /* max width of readable text */
  --pad:     1.5rem;  /* breathing room at the screen edge */
}

/* Dark mode. This reads the visitor's own operating system
   setting. You write no JavaScript and add no toggle: the
   browser tells us what they already asked for. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:       #131416;
    --paper-2:     #1c1e20;
    --ink:         #e7e7e2;
    --ink-soft:    #93958e;
    --rule:        #2c2e30;
    --accent:      #6fc49e;
    --accent-soft: #1b2a24;
  }
}


/* ---------------------------------------------------------
   2. BASE + LIGHT RESET
   --------------------------------------------------------- */

/* border-box makes padding and borders count INSIDE an
   element's stated width, which is how everyone assumes
   boxes work before they learn that they don't. */
*,
*::before,
*::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--step-0);
  line-height: 1.65;
  /* Stops iOS Safari inflating text in landscape. */
  -webkit-text-size-adjust: 100%;
}

img { max-width: 100%; height: auto; display: block; }

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover { text-decoration-thickness: 2px; }

/* Keyboard focus must always be visible. Someone navigating
   by Tab key needs to see where they are. */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Respect people who have asked their device to reduce motion. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ---------------------------------------------------------
   3. LAYOUT
   One centred column. Everything on the site sits in it.
   --------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--pad);
}

main { padding-block: 3rem 5rem; }


/* ---------------------------------------------------------
   4. MASTHEAD + NAV
   --------------------------------------------------------- */
.masthead {
  border-bottom: 1px solid var(--rule);
  padding-block: 1.5rem;
}

.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}

.masthead__name {
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}

.masthead__nav {
  display: flex;
  gap: 1.25rem;
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.06em;
}

.masthead__nav a {
  color: var(--ink-soft);
  text-decoration: none;
}

.masthead__nav a:hover { color: var(--ink); }

/* aria-current="page" is set in the HTML on whichever nav
   link matches the page you are on. It tells screen readers
   where they are, and it gives us something to style. One
   attribute doing two jobs. */
.masthead__nav a[aria-current="page"] {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}


/* ---------------------------------------------------------
   5. PROSE
   --------------------------------------------------------- */
.prose > * + * { margin-top: 1.35em; }

h1, h2, h3 {
  line-height: 1.2;
  letter-spacing: -0.011em;
  text-wrap: balance;   /* stops one lonely word on the last line */
}

h1 { font-size: var(--step-3); margin: 0; }
h2 { font-size: var(--step-2); margin-top: 2.75rem; }
h3 { font-size: var(--step-1); margin-top: 2rem; }

.prose h2 + *,
.prose h3 + * { margin-top: 0.9em; }

.lede {
  font-size: var(--step-1);
  color: var(--ink-soft);
  line-height: 1.5;
}

/* The small monospace line under a title: dates, statuses,
   read times. Used on both list pages and entry pages. */
.meta {
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.meta__sep { color: var(--rule); }

blockquote {
  margin: 2rem 0;
  padding-left: 1.25rem;
  border-left: 2px solid var(--rule);
  color: var(--ink-soft);
  font-style: italic;
}

code {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--paper-2);
  padding: 0.1em 0.35em;
  border-radius: 3px;
}

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin-block: 3rem;
}

ul, ol { padding-left: 1.25rem; }
li + li { margin-top: 0.5em; }


/* ---------------------------------------------------------
   6. ENTRY LISTS
   Shared by the Projects index and the Blog index, because
   they are the same shape: meta line, title, one-line summary.
   --------------------------------------------------------- */
.entry-list {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
}

.entry {
  padding-block: 1.75rem;
  border-top: 1px solid var(--rule);
}

.entry:last-child { border-bottom: 1px solid var(--rule); }

.entry + .entry { margin-top: 0; }

.entry__title {
  font-size: var(--step-1);
  margin: 0.5rem 0 0;
}

.entry__title a {
  color: var(--ink);
  text-decoration: none;
}

.entry__title a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.entry__summary {
  margin: 0.4rem 0 0;
  color: var(--ink-soft);
}


/* ---------------------------------------------------------
   7. STATUS LABELS
   The little square before the word is not decoration: its
   shape encodes the state. Filled means the project is alive,
   hollow means it is resting or done being touched.
   --------------------------------------------------------- */
.status {
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
}

.status::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin-right: 0.5em;
  vertical-align: 0.06em;
  background: currentColor;
}

.status--active   { color: var(--accent); }
.status--shipped  { color: var(--ink); }
.status--paused,
.status--archived { color: var(--ink-soft); }

.status--paused::before,
.status--archived::before {
  background: transparent;
  box-shadow: inset 0 0 0 1px currentColor;
}


/* ---------------------------------------------------------
   8. ANNOTATION BLOCK
   The "what I'd do differently" treatment. A note written in
   the margin after the work was done, so it should not look
   like just another paragraph.
   --------------------------------------------------------- */
.annotation {
  margin-top: 2.5rem;
  padding: 1.4rem 1.4rem 1.5rem;
  background: var(--accent-soft);
  border-left: 2px solid var(--accent);
}

.annotation__label {
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.9rem;
}

.annotation > :last-child { margin-bottom: 0; }
.annotation ul { margin: 0; }


/* ---------------------------------------------------------
   9. RELATED LINKS
   The cross-link between a project and its posts.
   --------------------------------------------------------- */
.related {
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.related__label {
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 0.9rem;
}

.related ul {
  list-style: none;
  margin: 0;
  padding: 0;
}


/* ---------------------------------------------------------
   10. FOOTER
   --------------------------------------------------------- */
.colophon {
  border-top: 1px solid var(--rule);
  padding-block: 1.75rem 3rem;
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

.colophon a { color: var(--ink-soft); }
.colophon a:hover { color: var(--accent); }


/* ---------------------------------------------------------
   11. ACCESSIBILITY HELPERS
   --------------------------------------------------------- */

/* Hidden until a keyboard user presses Tab, then it appears
   so they can jump past the nav straight to the content. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--paper);
  padding: 0.6rem 1rem;
  font-family: var(--mono);
  font-size: var(--micro);
  text-decoration: none;
  z-index: 10;
}

.skip-link:focus {
  left: 0;
}
