/* Replaces Overprint's bundled stylesheet. Tokens, type scale, and page geometry are shared with
   mcavus.com/assets/css/style.css — change one, change both.

   Sage and clay are too light to pass AA on the cream, so light mode uses hue-matched
   darker variants. */

:root {
  color-scheme: light;
  /* Overprint also emits --accent from `accent:` in overprint.yml, in a <style> block
     after this file, so in light mode the yml wins and this is a same-value echo. Dark
     mode's accent has no yml equivalent and is owned here. */
  --accent: #447f74; /* 4.51:1 */
  --label: #7f7365; /* 4.50:1 */
  --page-bg: #fdfcf8;
  --text-main: #151414; /* 17.91:1 */
  --text-soft: #7f7365; /* 4.50:1 */
  --meta: #747473; /* 4.56:1, deliberately not clay */
  --border-soft: rgba(144, 131, 116, 0.5);
  --rule-fade: rgba(144, 131, 116, 0.14);
  --link-line: rgba(64, 121, 111, 0.35);
  --surface: #f0ede4;

  /* Named apart from Overprint's --display and --serif so the yml's `font:` knob cannot
     reach in and change the body face. */
  --font-prose: "Spectral", Georgia, "Times New Roman", serif;
  --font-ui: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "Courier Prime", ui-monospace, "Courier New", monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --accent: #7fbbb0; /* 8.44:1 */
    --label: #908374; /* 4.98:1 */
    --page-bg: #151414;
    --text-main: #e1e0de; /* 13.94:1 */
    --text-soft: #908374; /* 4.98:1 */
    --meta: #9e9e9d; /* 6.86:1 */
    --border-soft: rgba(144, 131, 116, 0.32);
    --rule-fade: rgba(144, 131, 116, 0.08);
    --link-line: rgba(127, 187, 176, 0.35);
    --surface: #232322;
  }
}

/* the toggle's explicit choice beats the system preference */
:root[data-theme="dark"] {
  color-scheme: dark;
  --accent: #7fbbb0;
  --label: #908374;
  --page-bg: #151414;
  --text-main: #e1e0de;
  --text-soft: #908374;
  --meta: #9e9e9d;
  --border-soft: rgba(144, 131, 116, 0.32);
  --rule-fade: rgba(144, 131, 116, 0.08);
  --link-line: rgba(127, 187, 176, 0.35);
  --surface: #232322;
}

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

html {
  /* everything below is in rem, so this scales the whole page: 18px base, not 16 */
  font-size: 112.5%;
  -webkit-text-size-adjust: 100%;
  /* so short pages don't jump sideways relative to long ones */
  scrollbar-gutter: stable;
  background-color: var(--page-bg);
}

body {
  margin: 0;
  font-family: var(--font-prose);
  background-color: var(--page-bg);
  color: var(--text-main);
  -webkit-font-smoothing: antialiased;
}

/* ---- page shell ---------------------------------------------------------- */
/* Every value here is mcavus.com's and has to stay that way. */

.page {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.page-inner {
  /* .page centres by flex, so this needs an explicit width or it shrinks to its content
     and max-width never applies */
  width: 100%;
  max-width: 47.5rem;
  padding: 3rem 1.5rem;
  margin: 0 auto;
}

@media (min-width: 992px) {
  .page-inner {
    padding: 4.5rem 2rem;
  }
}

.hero-col {
  width: 100%;
}

@media (min-width: 992px) {
  .hero-col {
    max-width: 28.5rem;
    margin-inline: auto;
  }
}

/* ---- hero ---------------------------------------------------------------- */

.hero-header {
  margin-bottom: 2.25rem;
  margin-top: clamp(3rem, 8vh, 6rem);
}

.page-nav {
  margin-top: 0.5rem;
}

.page-nav .home-link {
  margin-top: 0;
}

/* with a back-link present, the hero's top margin belongs to the link */
.page-nav + .hero-header {
  margin-top: 2rem;
}

/* ---- identity ------------------------------------------------------------ */

.identity {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: 1.4rem;
}

.avatar {
  flex: none;
  display: block;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  overflow: hidden;
  /* hairline ring keeps the circle off the page in both themes */
  box-shadow: 0 0 0 1px var(--border-soft);
}

.avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  /* deter casual saving: no drag, no selection, no long-press callout, and right-clicks
     land on the wrapper so the browser offers no image-specific menu items */
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* One fluid size for the block; the name and location are sized in em so they keep their
   1.3 : 0.9 ratio at every width. nowrap plus a fluid size, not a breakpoint: the name's width
   steps while the column's grows continuously, so any fixed breakpoint leaves a band uncovered.
   The slope is the name's measured single-line width, 11.45em at 0.14em tracking, against a
   column of vw minus 151px of padding, avatar, and gap; 1.3rem is reached around 420px.
   Re-measure if the name text changes. */
.identity-text {
  display: block;
  font-size: clamp(0.8rem, calc(8.7vw - 13.5px), 1.3rem);
}

.hero-name {
  font-family: var(--font-ui);
  font-size: 1em;
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
  white-space: nowrap;
}

.hero-location {
  font-family: var(--font-ui);
  font-size: calc(1em * 0.9 / 1.3);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--meta);
  margin: 0.35rem 0 0;
}

/* A smaller portrait on phones, which also gives the name 9px more column. 27rem here is 432px:
   rem in a media query is the initial 16px, not the 112.5% set on html. */
@media (max-width: 27rem) {
  .avatar {
    width: 4rem;
    height: 4rem;
  }
}

.hero-lead {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--text-main);
  max-width: 38rem;
  margin: 0;
}

/* Same size as .hero-lead; 0.85rem matches mcavus.com's paragraph spacing. */
.hero-note {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--text-main);
  max-width: 38rem;
  margin: 0.85rem 0 0;
}

.hero-note a {
  font-family: var(--font-mono);
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--link-line);
  transition: border-bottom-color 160ms ease;
}

.hero-note a:hover {
  border-bottom-color: var(--accent);
}

.hero-note a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.page-title {
  font-family: var(--font-prose);
  font-size: 1.7rem;
  font-weight: 400;
  line-height: 1.25;
  color: var(--text-main);
  margin: 0;
}

/* ---- post list ----------------------------------------------------------- */

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

/* Every post carries its own rule, including the first. */
.post-item {
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-soft);
}

.post-item + .post-item {
  margin-top: 1.7rem;
}

/* clay, not the neutral --meta */
.post-date {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--label);
  margin-bottom: 0.4rem;
}

.post-item-title {
  font-family: var(--font-prose);
  font-size: 1.35rem;
  font-weight: 400;
  line-height: 1.3;
  margin: 0 0 0.5rem;
}

/* text-decoration rather than border-bottom: at this size a border sits on the line box and
   collides with the descenders, while an underline skips them and takes an offset. */
.post-item-title a {
  color: var(--text-main);
  text-decoration: underline;
  text-decoration-color: var(--link-line);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color 160ms ease, text-decoration-color 160ms ease;
}

/* .is-clickable is set by post-list.js, so the cursor and the whole-entry hover only appear
   once the entry really does respond to a click anywhere. */
.post-item-title a:hover,
.post-item.is-clickable:hover .post-item-title a {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

.post-item.is-clickable {
  cursor: pointer;
}

.post-item-title a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.post-excerpt {
  font-size: 0.96rem;
  line-height: 1.75;
  color: var(--text-main);
  margin: 0;
}

.draft-tag {
  font-family: var(--font-ui);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 0.05rem 0.3rem;
  margin-left: 0.4rem;
  vertical-align: 0.06em;
}

/* ---- single post --------------------------------------------------------- */

.post-title {
  font-family: var(--font-prose);
  font-size: 1.7rem;
  font-weight: 400;
  line-height: 1.25;
  color: var(--text-main);
  margin: 0 0 0.6rem;
}

.post-meta {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--label);
  margin: 0;
}

/* ---- rendered Markdown --------------------------------------------------- */

.post p {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--text-main);
  margin: 0 0 1.1rem;
}

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

.post h2 {
  position: relative;
  font-family: var(--font-prose);
  font-size: 1.28rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--text-main);
  margin: 2.4rem 0 0.75rem;
  padding-bottom: 0.45rem;
}

.post h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1.9rem;
  height: 1px;
  background: linear-gradient(to right, var(--label), var(--rule-fade));
}

.post h3 {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--label);
  margin: 1.9rem 0 0.6rem;
}

/* Courier Prime runs small, so no downsizing */
.post a {
  font-family: var(--font-mono);
  font-size: 1em;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--link-line);
  transition: border-bottom-color 160ms ease;
}

.post a:hover {
  border-bottom-color: var(--accent);
}

.post a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.post ul,
.post ol {
  margin: 0 0 1.1rem;
  padding-left: 1.3rem;
  font-size: 1rem;
  line-height: 1.75;
}

.post li {
  margin: 0 0 0.35rem;
}

.post li::marker {
  color: var(--meta);
}

.post blockquote {
  margin: 1.4rem 0;
  padding-left: 1.1rem;
  border-left: 1px solid var(--border-soft);
  font-style: italic;
  color: var(--text-soft);
}

.post blockquote p:last-child {
  margin-bottom: 0;
}

.post code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--surface);
  border-radius: 0.2rem;
  padding: 0.08em 0.3em;
}

/* --surface rather than a fixed dark plate, so it belongs to whichever theme is showing */
.post pre {
  margin: 0 0 1.3rem;
  padding: 0.9rem 1.1rem;
  background: var(--surface);
  border-radius: 0.34rem;
  box-shadow: 0 0 0 1px var(--border-soft);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.65;
  color: var(--text-main);
}

.post pre code {
  background: none;
  padding: 0;
  font-size: inherit;
  border-radius: 0;
}

.post hr {
  border: none;
  border-top: 1px solid var(--border-soft);
  margin: 2rem 0;
}

.post img {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 0 0 1px var(--border-soft);
}

.post table {
  width: 100%;
  margin: 0 0 1.3rem;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.post th,
.post td {
  text-align: left;
  padding: 0.45rem 0.6rem;
  border-bottom: 1px solid var(--border-soft);
}

.post th {
  font-family: var(--font-ui);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--meta);
}

/* ---- tags ---------------------------------------------------------------- */

.post-tags {
  margin: 2.25rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.post-tags a {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--accent);
  text-decoration: none;
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--border-soft);
  border-radius: 0.34rem;
  transition: border-color 160ms ease;
}

.post-tags a:hover {
  border-color: var(--accent);
}

.post-tags a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---- not found ----------------------------------------------------------- */

/* the error page is short, so it sits in the middle rather than at the top */
.page-centred {
  align-items: center;
}

/* positioned so the lamp can hang above it, and so switching themes never shifts it */
.error-plate {
  position: relative;
  margin: 0 0 2rem;
}

/* Gallery picture light: a slim bar on a short stem above the canvas, throwing a warm cone
   downward. Hidden in light mode — the room is already lit. */
.plate-lamp {
  display: none;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(100% + 0.45rem);
  width: 34%;
  max-width: 9rem;
  height: 0.28rem;
  border-radius: 0.2rem 0.2rem 0.12rem 0.12rem;
  /* machined housing: catches light along the top, falls to black underneath */
  background: linear-gradient(to bottom, #605e57 0%, #4a4842 38%, #2c2b27 76%, #171613 100%);
  box-shadow:
    0 -1px 0 rgba(255, 224, 165, 0.2),
    /* the lit underside — this is the lamp itself, not a reflection */ 0 1px 0 rgba(255, 219, 155, 0.8),
    0 2px 7px rgba(255, 206, 120, 0.4),
    0 5px 14px rgba(0, 0, 0, 0.5);
}

/* the stem holding it off the wall */
.plate-lamp::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 0.18rem;
  height: 0.62rem;
  transform: translateX(-50%);
  background: linear-gradient(to bottom, #2a2926 0%, #4c4a44 70%, #55534c 100%);
  border-radius: 0.09rem 0.09rem 0 0;
}

/* the cone in the air between lamp and canvas, widening as it falls */
.plate-lamp::after {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% - 1px);
  /* wide enough to spill past the fixture, narrow enough that it can never push the page
     sideways on a phone */
  width: 210%;
  max-width: 100vw;
  height: 2.2rem;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(
    46% 150% at 50% -8%,
    rgba(255, 216, 150, 0.36),
    rgba(255, 216, 150, 0.1) 44%,
    rgba(255, 216, 150, 0) 76%
  );
}

/* the frame exists so the picture light can overlay the canvas only, not the caption beneath */
.plate-frame {
  position: relative;
  display: block;
  border-radius: 2px;
  overflow: hidden;
  /* hairline keeps the plate from floating free of the page in dark mode */
  box-shadow: 0 0 0 1px var(--border-soft);
}

.error-plate img {
  display: block;
  width: 100%;
  height: auto;
  transition: filter 200ms ease;
}

/* In dark mode the canvas is turned down, then a warm pool is thrown across the top and
   allowed to fall away toward the bottom — the way a gallery lamp actually lights a painting.
   Light mode gets none of this. */
.plate-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 200ms ease;
  background:
    /* 1. hot band along the very top, where the lamp is nearest the canvas */
    linear-gradient(
      to bottom,
      rgba(255, 224, 165, 0.52) 0%,
      rgba(255, 224, 165, 0.24) 14%,
      rgba(255, 224, 165, 0) 32%
    ),
    /* 2. the pool of light, centred under the fixture. Reaches most of the way down so the
          boats on the water stay readable. */
      radial-gradient(
        95% 92% at 50% -6%,
        rgba(255, 219, 155, 0.44),
        rgba(255, 219, 155, 0.2) 52%,
        rgba(255, 219, 155, 0) 88%
      ),
    /* 3. falloff down the canvas, eased so the lower third does not crush */
      linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0) 30%,
        rgba(0, 0, 0, 0.16) 66%,
        rgba(0, 0, 0, 0.36) 100%
      ),
    /* 4. corners stay out of the beam */
      radial-gradient(125% 105% at 50% -5%, rgba(0, 0, 0, 0) 58%, rgba(0, 0, 0, 0.3) 100%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .error-plate img {
    filter: brightness(0.76) saturate(0.9);
  }

  :root:not([data-theme="light"]) .plate-frame::after {
    opacity: 1;
  }

  :root:not([data-theme="light"]) .plate-lamp {
    display: block;
  }
}

:root[data-theme="dark"] .error-plate img {
  filter: brightness(0.76) saturate(0.9);
}

:root[data-theme="dark"] .plate-frame::after {
  opacity: 1;
}

:root[data-theme="dark"] .plate-lamp {
  display: block;
}

/* museum-label voice: real Spectral italic, not a synthesised oblique */
.error-plate figcaption {
  font-family: var(--font-prose);
  font-style: italic;
  font-size: 0.68rem;
  letter-spacing: 0.01em;
  line-height: 1.5;
  color: var(--meta);
  margin-top: 0.65rem;
}

.error-code {
  font-family: var(--font-prose);
  font-size: clamp(4rem, 15vw, 6.5rem);
  line-height: 1;
  /* tracking is added to the right edge too, so pull that back to keep the three digits
     optically centred */
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  text-align: center;
  color: var(--accent);
  /* room below for the picture light to hang without displacing the painting. Kept in both
     themes so switching never reflows the page. */
  margin: 0 0 3.4rem;
}

.error-title {
  font-family: var(--font-prose);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--text-main);
  margin: 0.6rem 0 0;
}

/* ---- back link ----------------------------------------------------------- */

.home-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 2rem;
  font-family: var(--font-mono);
  color: var(--accent);
  text-decoration: none;
}

.home-link span {
  border-bottom: 1px solid var(--link-line);
  transition: border-bottom-color 160ms ease;
}

.home-link:hover span {
  border-bottom-color: var(--accent);
}

.home-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.home-arrow {
  flex: none;
  width: 0.9375rem;
  height: 0.9375rem;
}

/* ---- footer -------------------------------------------------------------- */

/* Inside .hero-col, so it shares the column's width and needs no padding of its own;
   .page-inner supplies the space below it. */
.site-footer {
  margin-top: 3rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule-fade);
}

.footer-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

/* flex:1 centres the text between the two buttons whatever their widths */
.footer-meta {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 0.7rem;
  margin: 0;
  font-family: var(--font-ui);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  color: var(--meta);
}

.icon-btn {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--meta);
  text-decoration: none;
  cursor: pointer;
  transition: color 160ms ease, background-color 160ms ease;
}

.icon-btn:hover {
  color: var(--accent);
  background: var(--surface);
}

.icon-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* own tooltip: the native title= waits about a second and arrives in OS chrome */
.icon-btn::after {
  content: attr(data-label);
  position: absolute;
  bottom: calc(100% + 0.35rem);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--font-ui);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: normal;
  line-height: 1.3;
  color: color-mix(in srgb, var(--text-main) 78%, transparent);
  background: var(--surface);
  border-radius: 0.34rem;
  padding: 0.22rem 0.56rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms ease;
}

.icon-btn:hover::after,
.icon-btn:focus-visible::after {
  opacity: 1;
}

/* 2rem boxes around a 16px glyph, so the glyph sits 10px inside the button edge. Pulling
   the outer two out by that inset lines the glyphs up with the column; only the hover
   background overhangs. */
.footer-row .icon-btn:first-child {
  margin-left: calc((2rem - 16px) / -2);
}

.footer-row .icon-btn:last-child {
  margin-right: calc((2rem - 16px) / -2);
}

/* otherwise these two centre their labels off the edge of a phone */
.footer-row .icon-btn:first-child::after {
  left: 0;
  transform: none;
}

.footer-row .icon-btn:last-child::after {
  left: auto;
  right: 0;
  transform: none;
}

/* Face and tracking inherit from .footer-meta. */
.built-with {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--link-line);
  transition: border-bottom-color 160ms ease;
}

.built-with:hover {
  border-bottom-color: var(--accent);
}

.built-with:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .post-item-title a,
  .post-tags a,
  .post a,
  .home-link span,
  .icon-btn,
  .icon-btn::after,
  .built-with,
  .error-plate img,
  .plate-frame::after {
    transition: none;
  }
}
