/* ============================================================
   jackneff.dev — standalone stylesheet (no framework)

   Direction: editorial column + systems/terminal accent.
   Hard edges, 1.5px rules, block buttons, a monospace metadata
   rail, and a lot of vertical air. Dark-first; light is derived.
   ============================================================ */

/* ---- 1. reset ------------------------------------------------ */

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

html { -webkit-text-size-adjust: 100%; overflow-x: clip; }

body, h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl { margin: 0; }

ul[class], ol[class] { list-style: none; padding: 0; }

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

button, input, select, textarea { font: inherit; color: inherit; }

:target { scroll-margin-top: 3rem; }

/* ---- 2. design tokens (dark-first) -------------------------- */

:root {
  /* neutrals — cool blue-green bias, pulled from favicon.svg (#10171c / #edf2f4) */
  --paper:      #0d1417;
  --surface:    #131e22;
  --surface-2:  #0a1013;
  --ink:        #e8eef1;
  --ink-soft:   #b3c0c6;
  --ink-muted:  #7c8d95;
  --rule:       #2f424b;
  --rule-soft:  #1b2830;
  --hatch-soft: rgba(232, 238, 241, 0.045);

  /* accent — amber. --accent fills; --accent-strong is link/text weight;
     --accent-ink is text placed on an --accent fill. */
  --accent:        #ffb020;
  --accent-strong: #ffc24a;
  --accent-ink:    #1a1204;

  /* code blocks are dark in BOTH schemes — these never change */
  --code-bg:     #0d1117;
  --code-ink:    #e6edf3;
  --code-border: #2b333c;

  /* type */
  --ff-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --ff-body:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ff-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --step-hero: clamp(2.7rem, 6.5vw, 4.25rem);
  --step-h1:   clamp(2.1rem, 4.6vw, 3rem);
  --step-h2:   clamp(1.35rem, 2.4vw, 1.6rem);
  --step-lead: clamp(1.1rem, 1.6vw, 1.25rem);
  --step-body: 1.0625rem;

  /* vertical rhythm — deliberately roomy */
  --space-2xl: clamp(5rem, 12vw, 9rem);
  --space-xl:  clamp(3.75rem, 8vw, 6rem);
  --space-lg:  clamp(2.25rem, 4.5vw, 3rem);
  --space-md:  1.6rem;

  /* layout */
  --rule-w:  1.5px;
  --measure: 42rem;
  --rail:    9rem;
  --col-gap: clamp(2rem, 5vw, 4rem);
  --wrap:    calc(var(--rail) + var(--col-gap) + var(--measure) + 5rem);
}

@media (prefers-color-scheme: light) {
  :root {
    --paper:      #f2f5f6;
    --surface:    #ffffff;
    --surface-2:  #e7ecee;
    --ink:        #16212a;
    --ink-soft:   #47555d;
    --ink-muted:  #66757c;
    --rule:       #bcc7cb;
    --rule-soft:  #dce3e5;
    --hatch-soft: rgba(22, 33, 42, 0.05);

    --accent:        #c26a00;
    --accent-strong: #9a4f00;
    --accent-ink:    #fff6e8;
  }
}

/* ---- 3. base elements ------------------------------------- */

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ff-body);
  font-size: var(--step-body);
  line-height: 1.75;
  /* lets full-bleed sections run to the viewport edge without a
     scrollbar-width sliver of horizontal scroll */
  overflow-x: clip;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--ff-display);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1 { font-size: var(--step-h1); letter-spacing: -0.03em; }
h2 { font-size: var(--step-h2); }
h3 { font-size: 1.15rem; letter-spacing: -0.015em; }

a {
  color: var(--accent-strong);
  text-decoration: none;
}
a:hover { text-decoration: underline; text-underline-offset: 3px; }

p { margin: 0; }

strong { font-weight: 600; color: var(--ink); }

hr {
  border: 0;
  border-top: var(--rule-w) solid var(--rule);
  margin-block: var(--space-lg);
}

code, kbd, pre, samp { font-family: var(--ff-mono); }

:not(pre) > code {
  font-size: 0.88em;
  background: var(--surface-2);
  border: 1px solid var(--rule-soft);
  padding: 0.08em 0.35em;
}

mark {
  background: none;
  color: var(--accent-strong);
  border: 1px solid var(--accent);
  font-family: var(--ff-mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 0.08rem 0.4rem;
  vertical-align: 0.14em;
}

::selection { background: var(--accent); color: var(--accent-ink); }

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

/* ---- 4. layout primitives -------------------------------- */

.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 2.5rem);
}

/* asymmetric column: [mono rail] [content measure] */
.row {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, var(--measure));
  gap: var(--col-gap);
  align-items: start;
}

.rail {
  font-family: var(--ff-mono);
  font-size: 0.7rem;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--ink-muted);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding-top: 0.4rem;
  word-break: break-word;
}
.rail a { color: var(--ink-muted); }
.rail a:hover { color: var(--accent-strong); text-decoration: none; }
.rail .now { color: var(--accent); }
.rail b { color: var(--ink-soft); font-weight: 500; }

/* ---- 5. site chrome ------------------------------------- */

.site-header {
  border-bottom: var(--rule-w) solid var(--rule);
}
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 1.75rem;
  padding-block: 1.5rem;
}

.brand {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.brand::before { content: "> "; color: var(--accent); }
.brand:hover { text-decoration: none; color: var(--accent-strong); }

.site-nav {
  display: flex;
  gap: 1.5rem;
  font-family: var(--ff-mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.site-nav a {
  position: relative;
  color: var(--ink-soft);
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.3rem;
  width: 100%;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.18s ease;
}
.site-nav a:hover { color: var(--accent-strong); text-decoration: none; }
.site-nav a:hover::after,
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }
.site-nav a[aria-current="page"] { color: var(--ink); }

/* hamburger toggle — hidden until JS + narrow viewport opt in */
.nav-toggle { display: none; }

.js .nav-toggle {
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.8rem;
  border: var(--rule-w) solid var(--rule);
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--ff-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.js .nav-toggle:hover {
  border-color: var(--accent);
  color: var(--accent-strong);
}
.site-header.is-open .nav-toggle {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 1rem;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.18s ease, opacity 0.18s ease;
}
.nav-toggle__bars {
  position: relative;
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
}
.nav-toggle__bars::before { top: -5px; }
.nav-toggle__bars::after { top: 5px; }

.site-header.is-open .nav-toggle__bars { background: transparent; }
.site-header.is-open .nav-toggle__bars::before { top: 0; transform: rotate(45deg); }
.site-header.is-open .nav-toggle__bars::after { top: 0; transform: rotate(-45deg); }

.site-footer {
  border-top: var(--rule-w) solid var(--rule);
  margin-top: var(--space-2xl);
}
.site-footer .wrap {
  padding-block: 2rem 3rem;
  font-family: var(--ff-mono);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  color: var(--ink-muted);
}
.site-footer code { color: var(--ink-soft); }

main { display: block; }

/* ---- 6. hero / page intro ------------------------------ */

/* hgroup is the markup the templates use for the page intro / hero */
hgroup { padding-block: var(--space-2xl) var(--space-lg); }
hgroup h1 {
  font-size: var(--step-hero);
  line-height: 1.02;
  letter-spacing: -0.035em;
  max-width: 15ch;
}
hgroup > p {
  margin-top: 1.85rem;
  font-size: var(--step-lead);
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 50ch;
}
/* a secondary-page hgroup (Blog, About, 404) is smaller than the home hero */
.page-head { padding-block: var(--space-xl) var(--space-lg); }
.page-head h1 { font-size: var(--step-h1); max-width: none; }

/* ---- 7. content sections ------------------------------ */

.section {
  padding-block: var(--space-xl);
  border-top: var(--rule-w) solid var(--rule);
}

/* full-bleed section variants — break the centered column out to the
   viewport edges, then pad the content back into alignment so the rail
   and measure line up with every other section. Use them to give a run
   of sections some light/dark rhythm. */
.section--fill,
.section--invert {
  margin-inline: calc(50% - 50vw);
  padding-inline: calc(50vw - 50%);
  border-bottom: var(--rule-w) solid var(--rule);
}
/* the next plain section would otherwise draw a second rule right under
   the panel's own bottom border */
.section--fill + .section,
.section--invert + .section { border-top: 0; }

/* quiet: a half-step off the page background, with the same faint
   engineering-paper hatch the project cards use */
.section--fill {
  background-color: var(--surface);
  background-image: repeating-linear-gradient(
    -45deg,
    var(--hatch-soft) 0 1px,
    transparent 1px 22px
  );
}

/* loud: flip ink and paper for the whole band */
.section--invert {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.section--invert .section-label,
.section--invert h2,
.section--invert h3 { color: var(--paper); }
.section--invert .rail,
.section--invert .rail b { color: color-mix(in srgb, var(--paper) 62%, transparent); }
.section--invert a { color: var(--accent); }
.section--invert a:hover { color: var(--accent-strong); }
.section--invert .link-list li,
.section--invert .project-list li { border-color: color-mix(in srgb, var(--paper) 20%, transparent); }
.section--invert .link-list a,
.section--invert .proj-name { color: var(--paper); }
.section--invert .proj-summary { color: color-mix(in srgb, var(--paper) 70%, transparent); }
.section--invert .proj-ico-box {
  border-color: color-mix(in srgb, var(--paper) 32%, transparent);
  color: var(--accent);
}

/* the mono section label that lives in the rail */
.section-label,
h2.section-label {
  font-family: var(--ff-mono);
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink);
  line-height: 1.4;
}
.section-label::before { content: "// "; color: var(--accent); }

/* ---- 8. project cards --------------------------------- */

.card-list {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}

.card-list > article {
  /* transform is composed from vars so hover-lift / scroll-reveal
     never fight in the cascade — each state just sets its own var */
  --lift: 0px;
  --rise: 0px;
  position: relative;
  border: var(--rule-w) solid var(--rule);
  background-color: var(--surface);
  /* faint diagonal hatch, like engineering paper */
  background-image: repeating-linear-gradient(
    -45deg,
    var(--rule-soft) 0 1px,
    transparent 1px 14px
  );
  padding: 1.65rem 1.8rem 1.75rem;
  transform: translate(var(--lift), var(--lift)) translateY(var(--rise));
  transition: border-color 0.15s ease, transform 0.18s ease, box-shadow 0.18s ease,
              opacity 0.55s ease;
}
/* lifts and casts a hard offset shadow on hover */
.card-list > article:hover {
  --lift: -3px;
  border-color: var(--ink-muted);
  box-shadow: 6px 6px 0 var(--rule-soft);
  z-index: 1;
}
/* stagger only the reveal, never the hover response */
.js .card-list > article.reveal { transition-delay: var(--reveal-delay, 0ms); }
.js .card-list > article.reveal:hover { transition-delay: 0s; }
.js .card-list > article.reveal:not(.is-visible) { --rise: 14px; }

/* featured projects get terminal-style corner crop marks rather than
   the ubiquitous accent left border */
.card-list > article.featured::before,
.card-list > article.featured::after {
  content: "";
  position: absolute;
  width: 1.4rem;
  height: 1.4rem;
  border: 0 solid var(--accent);
  pointer-events: none;
}
.card-list > article.featured::before {
  top: -1.5px;
  left: -1.5px;
  border-top-width: 3px;
  border-left-width: 3px;
}
.card-list > article.featured::after {
  right: -1.5px;
  bottom: -1.5px;
  border-right-width: 3px;
  border-bottom-width: 3px;
}

.card-list > article > header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.65rem;
}
.card-list > article > header strong { font-weight: 400; }
.card-list > article > header a {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.card-list > article > header a:hover { color: var(--accent-strong); text-decoration: none; }

.card-list > article > p { color: var(--ink-soft); }

/* inline live / code links on a card */
.links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
}
.card-list .links {
  font-family: var(--ff-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  flex-shrink: 0;
}
.card-list .links a { color: var(--ink-muted); }
.card-list .links a:hover { color: var(--accent-strong); text-decoration: none; }

/* ---- 9. block "retro" buttons ------------------------- */

.links [role="button"] {
  display: inline-block;
  font-family: var(--ff-mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.6rem 1.1rem;
  border: var(--rule-w) solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  box-shadow: 3px 3px 0 var(--rule);
  transition: transform 0.08s ease, box-shadow 0.08s ease,
              background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.links [role="button"].outline {
  border-color: var(--rule);
  color: var(--ink-soft);
}
.links [role="button"]:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
}
.links [role="button"]:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--rule);
}

/* ---- 10. tag filter chips ----------------------------- */

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.tags [role="button"] {
  font-family: var(--ff-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  padding: 0.3rem 0.7rem;
  border: var(--rule-w) solid var(--rule);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.tags [role="button"]:hover {
  border-color: var(--accent);
  color: var(--accent-strong);
  text-decoration: none;
}
.tags [role="button"].contrast {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* when the rail holds the filter, stack it under the label */
.rail .tags { flex-direction: column; align-items: stretch; gap: 0.4rem; }
.rail .tags [role="button"] { text-align: left; }

/* ---- 11. tag lists (kbd) ------------------------------ */

footer.tags { margin-top: 1rem; }

.tags kbd,
.rail .taglist span,
.rail .taglist a {
  font-family: var(--ff-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  background: none;
  border: 1px solid var(--rule);
  border-radius: 0;
  padding: 0.14rem 0.45rem;
  white-space: nowrap;
  line-height: 1.6;
}
footer.tags a { text-decoration: none; }
footer.tags a:hover kbd { color: var(--accent-strong); border-color: var(--accent); }

.rail .taglist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

/* ---- 12. article detail (project / blog post) -------- */

.backlink {
  font-family: var(--ff-mono);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-muted);
}
.backlink:hover { color: var(--accent-strong); text-decoration: none; }

/* detail pages (project / blog post) open with a bare .row — no hgroup or
   .section above it — so give it the breathing room every other page gets
   from its page-head */
main > .row:first-child { padding-top: var(--space-xl); }

article.project > header { padding-block: 0.4rem var(--space-lg); }
article.project > header hgroup { padding: 0; }
article.project > header hgroup h1 { max-width: 20ch; }
article.project > header hgroup > p {
  margin-top: 1.1rem;
  font-size: var(--step-lead);
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: 52ch;
}
article.project > header .links { margin-top: var(--space-md); }
article.project > footer.tags { margin-top: var(--space-lg); }

/* ---- 12b. project detail: hatched mat ---------------- */

/* Inverse of a project card. A card is a hatched box on blank paper; here
   the article sheet stays blank paper and the space around it — the rail
   gutter and the page margins — carries the same faint diagonal hatch.
   Low-contrast on purpose: texture, not a second surface.

   Five stacked gradients, each drawing one line per 130px (5-line) cycle at
   its own offset and alpha. Wide spacing keeps it sparse; the per-line mix
   toward transparent hand-varies the weight so no two adjacent lines match
   and it reads as drawn, not printed. --hatch-soft is the ceiling. */
.project-detail {
  --sheet-pad:   clamp(2rem, 5vw, 4rem);
  --sheet-pad-y: clamp(3rem, 8vw, 6rem);
  min-height: 100vh;
  background-color: var(--paper);
  /* fallback: uniform hatch where color-mix() isn't supported (the layered
     declaration below is dropped whole on parse failure, leaving this one) */
  background-image: repeating-linear-gradient(-45deg, var(--hatch-soft) 0 1px, transparent 1px 26px);
  background-image:
    repeating-linear-gradient(-45deg, var(--hatch-soft) 0 1px, transparent 1px 130px),
    repeating-linear-gradient(-45deg, transparent 0 26px,
      color-mix(in srgb, var(--hatch-soft), transparent 50%) 26px 27px, transparent 27px 130px),
    repeating-linear-gradient(-45deg, transparent 0 52px,
      color-mix(in srgb, var(--hatch-soft), transparent 18%) 52px 53px, transparent 53px 130px),
    repeating-linear-gradient(-45deg, transparent 0 78px,
      color-mix(in srgb, var(--hatch-soft), transparent 40%) 78px 79px, transparent 79px 130px),
    repeating-linear-gradient(-45deg, transparent 0 104px,
      color-mix(in srgb, var(--hatch-soft), transparent 28%) 104px 105px, transparent 105px 130px);
}

/* a wide band of hatch above and below the sheet */
.project-detail main > .row:first-child {
  padding-top: var(--space-2xl);
  padding-bottom: var(--space-2xl);
}

/* widen just the content track (and main) by the sheet padding so the blank
   border around the article doesn't eat into the text measure. Header and
   footer keep the normal wrap width. */
.project-detail main.wrap { max-width: calc(var(--wrap) + 2 * var(--sheet-pad)); }
.project-detail main > .row:first-child {
  grid-template-columns: var(--rail) minmax(0, calc(var(--measure) + 2 * var(--sheet-pad)));
}

.project-detail article.project {
  background: var(--paper);
  padding: var(--sheet-pad-y) var(--sheet-pad);
}

@media (max-width: 800px) {
  .project-detail main > .row:first-child { grid-template-columns: 1fr; }
  .project-detail article.project {
    padding: var(--space-lg) clamp(1.1rem, 5vw, 1.6rem);
  }
}

/* ---- 13. prose (rendered Markdown) ------------------- */

.prose {
  max-width: var(--measure);
}
.prose > * + * { margin-top: 1.85rem; }
.prose > :first-child { margin-top: 0; }

.prose h2 { margin-top: 3rem; font-size: 1.45rem; }
.prose h3 { margin-top: 2.4rem; font-size: 1.15rem; }
.prose h2 + *, .prose h3 + * { margin-top: 1rem; }

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

.prose ul, .prose ol { padding-left: 1.4rem; }
.prose li + li { margin-top: 0.5rem; }
.prose li::marker { color: var(--ink-muted); }

.prose blockquote {
  border-left: 3px solid var(--rule);
  padding-left: 1.2rem;
  color: var(--ink-soft);
  font-style: italic;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.prose th, .prose td {
  text-align: left;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--rule);
}
.prose th { font-family: var(--ff-mono); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }

/* code blocks: dark in both colour schemes */
.prose pre {
  background: var(--code-bg);
  color: var(--code-ink);
  border: var(--rule-w) solid var(--code-border);
  border-left: 3px solid var(--accent);
  padding: 1.15rem 1.35rem;
  overflow-x: auto;
  font-size: 0.86rem;
  line-height: 1.65;
}
.prose pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: inherit;
}
.prose .highlight { border-left: 3px solid var(--accent); }
.prose .highlight pre { border-left: 0; }

/* ---- 14. blog index --------------------------------- */

.post-list { display: flex; flex-direction: column; }

.post-list > article {
  padding-block: 2rem;
  border-top: var(--rule-w) solid var(--rule-soft);
}
.post-list > article:first-child { border-top: 0; padding-top: 0.4rem; }

.post-list > article > header {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}
.post-list > article > header a {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.post-list > article > header a:hover { color: var(--accent-strong); text-decoration: none; }
.post-list > article > p { color: var(--ink-soft); }
.post-list > article > p + p { margin-top: 0.35rem; }
.post-list > article > p small {
  font-family: var(--ff-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
}

/* ---- 15. about ------------------------------------- */

.about-body { max-width: var(--measure); }
.about-body > p + p { margin-top: 1.65rem; }
.about-body .link-list { margin-top: 0.5rem; }

.link-list { max-width: var(--measure); }
.link-list li {
  padding-block: 0.9rem;
  border-top: var(--rule-w) solid var(--rule-soft);
}
.link-list li:first-child { border-top: 0; }
.link-list a {
  font-family: var(--ff-display);
  font-weight: 500;
  color: var(--ink);
}
.link-list a:hover { color: var(--accent-strong); }

/* project icon box — shared by the About list and the detail-page crest
   (glyph markup comes from portfolio/icons.py via the project_icon global) */
.project-list {
  max-width: var(--measure);
  margin-top: 0.5rem;
}
.project-list li {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 1.1rem;
  align-items: start;
  padding-block: 1.15rem;
  border-top: var(--rule-w) solid var(--rule-soft);
}
.project-list li:first-child { border-top: 0; }

.proj-ico-box {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: var(--rule-w) solid var(--rule);
  background: var(--surface);
  color: var(--accent);
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.proj-ico { width: 1.3rem; height: 1.3rem; }

.project-list li:hover .proj-ico-box {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}

/* detail-page crest: same box, slightly larger, leads into the title */
.proj-crest {
  width: 3rem;
  height: 3rem;
  margin-bottom: 1.15rem;
}
.proj-crest .proj-ico { width: 1.6rem; height: 1.6rem; }

.proj-text { padding-top: 0.15rem; }
.proj-name {
  display: block;
  font-family: var(--ff-display);
  font-weight: 600;
  color: var(--ink);
}
.proj-name:hover { color: var(--accent-strong); text-decoration: none; }
.project-list li:hover .proj-name { color: var(--accent-strong); }
.proj-summary {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* ---- 16. scroll reveal --------------------------- */

/* site.js adds .reveal only when motion is allowed; the initial
   hidden state is scoped to .js so no-JS visitors see everything. */
/* :where() keeps zero specificity so the project-card rule (which composes
   its own transform from vars) always wins the cascade */
.js :where(.reveal) {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.55s ease,
              transform 0.55s cubic-bezier(0.2, 0.6, 0.2, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
.js :where(.reveal.is-visible) {
  opacity: 1;
  transform: none;
}

/* ---- 17. motion ----------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js :where(.reveal) { opacity: 1; transform: none; }
  .card-list > article { --rise: 0px; }
}

/* ---- 18. responsive ------------------------------- */

/* mobile nav: below 640px the toggle drives a stacked panel of
   block buttons, styled after the project tag-filter chips */
@media (max-width: 640px) {
  .js .nav-toggle { display: inline-flex; }

  .js .site-nav {
    order: 3;
    flex-basis: 100%;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 0.28s ease, opacity 0.2s ease, margin-top 0.28s ease;
  }
  .js .site-header.is-open .site-nav {
    max-height: 70vh;
    opacity: 1;
    margin-top: 1rem;
  }

  .js .site-nav a {
    padding: 0.85rem 1rem;
    border: var(--rule-w) solid var(--rule);
    color: var(--ink-soft);
    font-family: var(--ff-mono);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
  }
  .js .site-nav a::after { content: none; }
  .js .site-nav a:hover,
  .js .site-nav a:focus-visible {
    border-color: var(--accent);
    color: var(--accent-strong);
    background: var(--surface);
  }
  .js .site-nav a[aria-current="page"] {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--accent-ink);
  }
}

@media (max-width: 800px) {
  .row {
    grid-template-columns: 1fr;
    gap: 1.1rem;
  }
  /* let the single column shrink to the viewport — without this a wide
     <pre> in a blog post drags the whole track past the screen edge */
  .row > * { min-width: 0; }
  .rail {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 1.25rem;
    padding-top: 0;
  }
  .rail .tags { flex-direction: row; align-items: center; }
  .rail .taglist { width: 100%; }
}

@media (max-width: 520px) {
  .card-list > article > header { flex-direction: column; gap: 0.4rem; }
  .site-header .wrap { gap: 0.75rem; }
}
