/* Define broad grayscale design tokens for the hand-built personal web theme. */
:root {
  color-scheme: dark;
  --paper: #101010;
  --paper-deep: #1c1c1c;
  --ink: #f1f1f1;
  --muted: #c8c8c8;
  --line: #2d2d2d;
  --lightgray: #333333;
  --darkgray: #d0d0d0;
  --blue: #9bb0bd;
  --red: #db8e88;
  --green: #8daeb3;
  --yellow: #e0bc7e;
  --gray: #777777;
  --secondary: #d9d9d9;
  --tertiary: #a8a8a8;
  --highlight: #c59b8d1f;
  --rust: #db8e88;
  --clay: #deaea0;
  --sage: #aebd9f;
  --pine: #8daeb3;
  --mauve: #c9b1b9;
  --shadow: none;
  --radius: 0;
  --measure: 42rem;
  --glass-width: 44rem;
  /* Keep shared theme-dependent grayscale surfaces and isolated accents in tokens so every page mode switches together. */
  --rule: rgba(240, 240, 240, 0.26);
  --banner-border: rgba(245, 245, 245, 0.72);
  --quick-link-border: rgba(197, 155, 141, 0.24);
  --quick-link-border-strong: rgba(197, 155, 141, 0.46);
  --quick-link-hover: rgba(197, 155, 141, 0.18);
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-wash-top: rgba(255, 255, 255, 0.045);
  --glass-wash-bottom: rgba(0, 0, 0, 0.08);
  --glass-fill: rgba(0, 0, 0, 0.24);
  --glass-fallback: rgba(0, 0, 0, 0.34);
  --glass-highlight: rgba(255, 255, 255, 0.07);
  --glass-shadow: rgba(0, 0, 0, 0.28);
  --callout-bg: rgba(32, 57, 54, 0.82);
  --callout-title: #4ee6e9;
  --tag-orange: #ff9d66;
  --tag-cyan: #00d4ff;
  --tag-blue: #6da2ff;
  --tag-red: #ff6a45;
  --tag-green: #7dff9a;
  --tag-yellow: #e7c15f;
}

/* Swap the site tokens to the inverted grayscale palette when the user chooses light mode. */
:root[data-theme="light"] {
  color-scheme: light;
  --paper: #f7f7f7;
  --paper-deep: #e6e6e6;
  --ink: #171717;
  --muted: #525252;
  --line: #d8d8d8;
  --lightgray: #d8d8d8;
  --darkgray: #444444;
  --blue: #728c99;
  --red: #bf6159;
  --green: #56706b;
  --yellow: #cc9e54;
  --gray: #9a9a9a;
  --secondary: #2b2b2b;
  --tertiary: #707070;
  --highlight: #a67c6d1a;
  --rust: #bf6159;
  --clay: #c78d75;
  --sage: #869c7a;
  --pine: #56706b;
  --mauve: #9d868e;
  /* Mirror the dark-mode surface tokens with light grayscale values and isolated accents for all shared page modules. */
  --rule: rgba(0, 0, 0, 0.22);
  --banner-border: #111111;
  --quick-link-border: rgba(166, 124, 109, 0.24);
  --quick-link-border-strong: rgba(166, 124, 109, 0.44);
  --quick-link-hover: rgba(166, 124, 109, 0.16);
  --glass-border: rgba(0, 0, 0, 0.16);
  --glass-wash-top: rgba(255, 255, 255, 0.48);
  --glass-wash-bottom: rgba(0, 0, 0, 0.035);
  --glass-fill: rgba(255, 255, 255, 0.28);
  --glass-fallback: rgba(255, 255, 255, 0.42);
  --glass-highlight: rgba(255, 255, 255, 0.34);
  --glass-shadow: rgba(0, 0, 0, 0.16);
  --callout-bg: rgba(209, 232, 229, 0.72);
  --callout-title: #006f78;
  --tag-orange: #d76f3f;
  --tag-cyan: #008fb2;
  --tag-blue: #4f7ed8;
  --tag-red: #d94f32;
  --tag-green: #2a9b55;
  --tag-yellow: #b88722;
}

/* Keep box sizing predictable for dense, handmade layouts. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Give the page a neutral paper surface that leaves quiet gutters around the center column. */
html {
  min-height: 100%;
  background:
    var(--paper);
  scroll-behavior: smooth;
}

/* Set readable base typography without depending on external fonts. */
body {
  margin: 0;
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Code", "Liberation Mono", Menlo, monospace;
  font-size: clamp(0.78rem, 0.75rem + 0.14vw, 0.86rem);
  line-height: 1.42;
  overflow-x: hidden;
  position: relative;
}

/* Keep the interactive background fixed behind every page layer. */
.portfolio-force-field-canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

/* Lift normal page content above the animated background. */
body > :not(.portfolio-force-field-canvas) {
  position: relative;
  z-index: 1;
}

/* Make media responsive by default. */
img,
svg {
  max-width: 100%;
  height: auto;
}

/* Keep links visibly part of the page texture. */
a {
  color: var(--secondary);
  text-decoration-thickness: 0.11em;
  text-underline-offset: 0.16em;
}

/* Style inline topic links as bold highlighted boxes without underline chrome. */
.quick-link {
  display: inline;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  border: 1px solid var(--quick-link-border);
  padding: 0.02rem 0.22rem;
  background: var(--highlight);
  color: var(--secondary);
  font-weight: 800;
  text-decoration: none;
}

/* Give topic boxes a stronger affordance on hover and keyboard focus. */
.quick-link:hover,
.quick-link:focus-visible {
  border-color: var(--quick-link-border-strong);
  background: var(--quick-link-hover);
}

/* Typeset lightweight inline formulas while preserving the handmade monospace voice. */
.inline-math {
  display: inline-block;
  margin: 0 0.08em;
  color: var(--yellow);
  font-family: "Times New Roman", "STIX Two Math", serif;
  font-size: 1.04em;
  font-style: italic;
  line-height: 1;
  vertical-align: -0.03em;
  white-space: nowrap;
}

/* Keep formula subscripts and superscripts compact inside dense project prose. */
.inline-math sub,
.inline-math sup {
  font-size: 0.68em;
  line-height: 0;
}

/* Keep named math functions upright inside italic formula spans. */
.inline-math .math-function {
  font-style: normal;
}

/* Draw overbar notation for compact inline and display equations. */
.math-overline {
  text-decoration: overline;
  text-decoration-thickness: 0.08em;
}

/* Format standalone equations as centered technical callouts that match inline formula styling. */
.math-block {
  max-width: 100%;
  margin: 0.58rem 0 0.72rem;
  border-left: 2px solid var(--yellow);
  padding: 0.42rem 0.58rem;
  background: color-mix(in srgb, var(--yellow) 8%, transparent);
  color: var(--yellow);
  font-family: "Times New Roman", "STIX Two Math", serif;
  font-size: 1.04em;
  font-style: italic;
  line-height: 1.35;
  overflow-x: auto;
  text-align: center;
}

/* Center piecewise equations as a grouped formula while allowing cases to scroll on narrow screens. */
.math-cases {
  align-items: center;
  display: flex;
  gap: 0.34rem;
  justify-content: center;
}

/* Scale the case brace so it visually spans the three piecewise rows. */
.math-case-brace {
  display: inline-block;
  font-size: 5.6em;
  font-style: normal;
  line-height: 0.72;
  margin: 0 -0.06em 0 -0.02em;
  transform: scaleX(0.62);
  transform-origin: center;
}

/* Reset case-rule tables inside math callouts so they read like equation rows. */
.math-cases table {
  border-collapse: collapse;
  min-width: 24rem;
}

/* Space piecewise case cells tightly enough to preserve the equation shape. */
.math-cases td {
  padding: 0.08rem 0.5rem 0.08rem 0;
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
}

/* Pin the quick-links sub window beside the main glass margin on wide screens. */
body .quick-links-window {
  position: fixed;
  top: 1.15rem;
  left: calc(50% + (min(var(--glass-width), calc(100vw - 1.5rem)) / 2) + 1rem);
  width: clamp(10.5rem, 14vw, 14rem);
  max-height: min(28rem, calc(100vh - 2.3rem));
  border: 0;
  background: transparent;
  overflow: hidden;
}

/* Give the quick-links window a compact file-pane heading. */
.quick-links-window h2 {
  border-bottom: 1px solid var(--rule);
  margin: 0;
  padding: 0.58rem 0.64rem 0.48rem;
  color: var(--ink);
  font-size: 0.76rem;
  line-height: 1;
  text-transform: uppercase;
}

/* Let the quick-links list scroll only when it outgrows the window. */
.quick-links-window-nav {
  max-height: calc(min(28rem, calc(100vh - 2.3rem)) - 2rem);
  overflow-y: auto;
  scrollbar-color: var(--secondary) transparent;
  scrollbar-width: thin;
}

/* Reset the quick-links index so each item reads like a folder-list row. */
.quick-links-window ol {
  display: grid;
  gap: 0.05rem;
  margin: 0;
  padding: 0.42rem 0.48rem 0.52rem;
  list-style: none;
}

/* Style quick-link window anchors as compact, wrapping list entries. */
.quick-links-window a {
  display: block;
  padding: 0.28rem 0.22rem;
  color: var(--secondary);
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1.18;
  text-decoration: none;
}

/* Keep hover and keyboard states quiet while still making rows feel clickable. */
.quick-links-window a:hover,
.quick-links-window a:focus-visible {
  background: var(--highlight);
  color: var(--ink);
}

/* Provide an obvious keyboard focus state across the site. */
:focus-visible {
  outline: 3px solid var(--secondary);
  outline-offset: 3px;
}

/* Create the subtle translucent main-column background shown behind all content. */
.content-glass {
  width: min(var(--glass-width), calc(100% - 1.5rem));
  margin: 1.15rem auto 2rem;
  border: 1px solid var(--glass-border);
  background:
    linear-gradient(180deg, var(--glass-wash-top), var(--glass-wash-bottom)),
    var(--glass-fill);
  backdrop-filter: blur(5px) saturate(112%);
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    0 18px 64px var(--glass-shadow);
}

/* Keep older browsers usable when backdrop-filter is unavailable. */
@supports not (backdrop-filter: blur(10px)) {
  .content-glass {
    background: var(--glass-fallback);
  }
}

/* Anchor the main navigation inside the same centered column as the content. */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: min(var(--measure), calc(100% - 2rem));
  margin: 0 auto;
  padding: 0.85rem 0 0.45rem;
  background: transparent;
}

/* Make the home link feel like a site label rather than a logo asset. */
.site-mark {
  color: var(--ink);
  font-weight: 900;
  text-decoration: none;
  text-transform: uppercase;
}

/* Keep navigation compact and naturally wrappable on small screens. */
.site-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.22rem 0.62rem;
}

/* Keep the theme toggle visually aligned with the compact text navigation. */
.theme-toggle {
  border: 1px solid var(--lightgray);
  padding: 0.05rem 0.35rem;
  background: transparent;
  color: var(--secondary);
  cursor: pointer;
  font: inherit;
  font-size: 0.74rem;
  font-weight: 700;
}

/* Give the theme toggle a small hover/focus affordance without adding a new color. */
.theme-toggle:hover,
.theme-toggle:focus-visible {
  background: var(--highlight);
}

/* Keep the live local time visually aligned with compact header navigation. */
.header-time {
  border: 1px solid var(--yellow);
  padding: 0.05rem 0.35rem;
  background: color-mix(in srgb, var(--yellow) 14%, transparent);
  color: var(--yellow);
  font-size: 0.74rem;
  font-weight: 700;
}

/* Style nav links as plain text labels with a hover highlight. */
.site-nav a {
  color: var(--ink);
  font-size: 0.74rem;
  font-weight: 700;
  text-decoration-color: transparent;
}

/* Show active and hovered navigation states with the same handmade mark. */
.site-nav a:hover,
.site-nav a[aria-current="page"] {
  text-decoration-color: var(--red);
}

/* Place the generated breadcrumb path at the top of every page column. */
.site-breadcrumb {
  width: min(var(--measure), calc(100% - 2rem));
  margin: 0 auto;
  padding: 0.15rem 0 0.2rem;
  color: var(--secondary);
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: none;
}

/* Keep breadcrumb segments compact and naturally wrapping on narrow screens. */
.site-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.08rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Add slash separators between breadcrumb levels without making them separate links. */
.site-breadcrumb li + li::before {
  content: "/";
  margin: 0 0.28rem 0 0.2rem;
  color: var(--tertiary);
}

/* Match breadcrumb links to the existing small uppercase route labels. */
.site-breadcrumb a {
  color: var(--secondary);
  text-decoration-color: transparent;
}

/* Keep breadcrumb hover and keyboard states obvious but restrained. */
.site-breadcrumb a:hover,
.site-breadcrumb a:focus-visible {
  text-decoration-color: var(--secondary);
}

/* Hide old static path labels only after the generated clickable breadcrumb is available. */
.has-site-breadcrumb .page-kicker {
  display: none;
}

/* Hide old static path labels when the breadcrumb is authored directly in the page. */
.site-breadcrumb + .page-shell .page-kicker {
  display: none;
}

/* Constrain page content to a narrow center column with blank outer gutters. */
.page-shell {
  width: min(var(--measure), calc(100% - 2rem));
  margin: 0.48rem auto 2.2rem;
}

/* Stack the homepage as a continuous personal stream instead of a card grid. */
.home-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.05rem;
}

/* Hide semantic-only text while keeping it available to assistive technology. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Keep temporary clipboard fields invisible without needing inline styles under the site CSP. */
.clipboard-copy-buffer {
  position: fixed;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
}

/* Size the temporary homepage banner within the centered content column. */
.home-banner {
  display: block;
  width: 100%;
  aspect-ratio: 10 / 3;
  border: 1px solid var(--banner-border);
  background: transparent;
  object-fit: cover;
  margin: 0.55rem 0 0.8rem;
}

/* Use an eyebrow as small metadata, not decorative marketing copy. */
.eyebrow {
  margin: 0 0 0.55rem;
  color: var(--secondary);
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
}

/* Keep long intro text readable beside the large heading. */
.intro-copy {
  max-width: 48rem;
  margin: 0.7rem 0 0;
  font-size: 0.86rem;
}

/* De-emphasize contextual helper copy without hiding it. */
.small-print {
  max-width: 46rem;
  margin: 0.5rem 0 0;
  color: var(--muted);
}

/* Make feed, project, and content headings compact and scannable. */
.feed-section h2,
.project-strip h2,
.content-panel h1,
.content-panel h2 {
  margin-bottom: 0.48rem;
  margin-top: 0;
  line-height: 1.1;
}

/* Make content-page subtitles larger and easier to scan between prose blocks. */
.content-panel h3 {
  margin: 1rem 0 0.38rem;
  color: var(--ink);
  font-size: 1.18rem;
  line-height: 1.15;
}

/* Separate notes inside feeds with spacing and a small rule. */
.feed-section .note + .note,
.notes-list .note + .note {
  border-top: 1px solid var(--rule);
  margin-top: 0.8rem;
  padding-top: 0.8rem;
}

/* Give feed notes local spacing without panel chrome. */
.note {
  padding: 0;
  box-shadow: none;
}

/* Keep note metadata small and mechanical. */
.note-meta {
  margin: 0 0 0.28rem;
  color: var(--muted);
  font-size: 0.68rem;
}

/* Remove extra top margin from note titles. */
.note h2,
.note h3 {
  margin-bottom: 0.38rem;
  margin-top: 0;
}

/* Align section titles and utility links in one row. */
.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

/* Display projects as a vertical record list rather than cards. */
.project-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.72rem;
}

/* Keep project entries unboxed and separated by flow. */
.project-card {
  overflow: hidden;
  box-shadow: none;
}

/* Let homepage project shelf images act as compact banner headers. */
.project-card img {
  display: block;
  width: min(38rem, 100%);
  aspect-ratio: 6 / 1;
  object-fit: cover;
  border: 1px solid var(--banner-border);
  margin-inline: auto;
  background: transparent;
}

/* Keep homepage shelf banners close under their project titles. */
.project-card-banner {
  margin: 0.22rem auto 0.42rem;
}

/* Arrange project tool tags as bright, compact rounded labels below each banner. */
.project-tool-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.32rem;
  max-width: 100%;
  margin: 0.2rem 0 0.55rem;
  padding: 0;
  list-style: none;
}

/* Give project tool labels a terminal-bright chip treatment without making them links. */
.project-tool-tags li {
  border: 1px solid currentColor;
  border-radius: 0.28rem;
  padding: 0.08rem 0.36rem;
  background: color-mix(in srgb, currentColor 14%, transparent);
  font-size: 0.68rem;
  font-weight: 900;
  line-height: 1.2;
}

/* Color the first tag in each cycle with a warm orange accent. */
.project-tool-tags li:nth-child(6n + 1) {
  color: var(--tag-orange);
}

/* Color the second tag in each cycle with a cyan accent. */
.project-tool-tags li:nth-child(6n + 2) {
  color: var(--tag-cyan);
}

/* Color the third tag in each cycle with a blue accent. */
.project-tool-tags li:nth-child(6n + 3) {
  color: var(--tag-blue);
}

/* Color the fourth tag in each cycle with a red-orange accent. */
.project-tool-tags li:nth-child(6n + 4) {
  color: var(--tag-red);
}

/* Color the fifth tag in each cycle with a green accent. */
.project-tool-tags li:nth-child(6n + 5) {
  color: var(--tag-green);
}

/* Color the sixth tag in each cycle with a yellow accent. */
.project-tool-tags li:nth-child(6n) {
  color: var(--tag-yellow);
}

/* Keep project shelf summary copy compact beneath the banner and tool tags. */
.project-entry-summary {
  color: var(--muted);
}

/* Highlight project status labels as inline accent tags inside project summaries. */
.project-status-tag {
  display: inline-block;
  border: 1px solid var(--tag-yellow);
  border-radius: 0.24rem;
  margin-right: 0.28rem;
  padding: 0.03rem 0.24rem;
  background: color-mix(in srgb, var(--tag-yellow) 16%, transparent);
  color: var(--tag-yellow);
  font-size: 0.78em;
  line-height: 1.2;
  vertical-align: 0.06em;
}

/* Space project overview sections as a readable project page scaffold. */
.project-overview-section {
  margin-top: 1rem;
}

/* Wrap Obsidian-style callouts without adding extra card treatment around the body. */
.obsidian-callout {
  max-width: 100%;
  margin: 0.62rem 0 0.82rem;
  border-radius: 0.34rem;
  background: var(--callout-bg);
  overflow: hidden;
}

/* Recreate the Obsidian callout title bar within the grayscale site palette. */
.obsidian-callout-title {
  display: flex;
  align-items: center;
  gap: 0.42rem;
  min-height: 2.95rem;
  padding: 0.68rem 0.86rem 0.38rem;
  color: var(--callout-title);
  font-size: 1.04rem;
  font-weight: 800;
}

/* Keep the leading marker compact while giving it icon-like emphasis. */
.obsidian-callout-icon {
  display: inline-grid;
  width: 1.18rem;
  height: 1.18rem;
  border: 2px solid currentColor;
  border-radius: 50%;
  place-items: center;
  font-size: 0.78rem;
  line-height: 1;
}

/* Push the source-code hint to the right edge of the callout header. */
.obsidian-callout-code {
  margin-left: auto;
  color: var(--muted);
  font-size: 0.92rem;
}

/* Keep the callout prose inside the same blue highlighted note area. */
.obsidian-callout-body {
  padding: 0 0.86rem 0.76rem;
  color: var(--ink);
}

/* Preserve regular prose weight inside the highlighted note body. */
.obsidian-callout-body p {
  font-weight: 400;
}

/* Let technical reference tables scroll horizontally instead of squeezing dense labels. */
.technical-table-wrap {
  max-width: 100%;
  margin: 0.58rem 0 0.78rem;
  overflow-x: auto;
}

/* Style note tables as simple ruled data blocks that match the handmade page system. */
.technical-table {
  width: 100%;
  min-width: 32rem;
  border-collapse: collapse;
  color: var(--ink);
  font-size: 0.78rem;
}

/* Keep table header labels distinct from body copy without adding card chrome. */
.technical-table th {
  border-bottom: 1px solid var(--rule);
  padding: 0.36rem 0.48rem;
  color: var(--secondary);
  font-weight: 900;
  text-align: left;
}

/* Give table body rows a light rule so long geometry descriptions remain scannable. */
.technical-table td {
  border-bottom: 1px solid var(--rule);
  padding: 0.42rem 0.48rem;
  vertical-align: top;
}

/* Keep update links compact in the project overview sections. */
.project-update-list {
  display: grid;
  gap: 0.4rem;
  max-width: 100%;
  margin: 0.38rem 0 0.65rem;
  padding: 0;
  list-style: none;
}

/* Lay each update entry out consistently even when more links are added. */
.project-update-list li {
  display: grid;
  gap: 0.08rem;
}

/* Inset technical notes with a simple one-pixel outline inside the main column. */
.outlined-cycle-note {
  border: 1px solid var(--rule);
  margin: 0.78rem 0.72rem 0.65rem;
  padding: 0.68rem 0.78rem;
}

/* Give cycle-stage headings subtitle weight without overpowering the section title. */
.outlined-cycle-note h4 {
  margin: 0.62rem 0 0.28rem;
  color: var(--ink);
  font-size: 1.02rem;
}

/* Remove extra top space from the first cycle-stage heading in the outlined box. */
.outlined-cycle-note h4:first-child {
  margin-top: 0;
}

/* Keep optimization bullets tight inside the outlined cycle note. */
.outlined-cycle-note ul {
  margin: 0.2rem 0 0.55rem;
  padding-left: 1.25rem;
}

/* Reduce vertical gaps between individual optimization bullet lines. */
.outlined-cycle-note li {
  margin: 0.06rem 0;
}

/* Place paired project photos in a tight two-column row within update posts. */
.paired-project-images {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.62rem;
  margin: 0.75rem 0 0.85rem;
}

/* Crop paired project photos evenly so mismatched source ratios align. */
.paired-project-images img {
  width: 100%;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--banner-border);
  object-fit: cover;
}

/* Pan the track-bike jig CAD crops so the fixtures sit closer to the center of each square. */
.paired-project-images img.track-jig-crop-angled {
  object-position: 34% 50%;
}

/* Keep the side jig view from reading too left-heavy in the paired square crop. */
.paired-project-images img.track-jig-crop-side {
  object-position: 38% 50%;
}

/* Display single project figures full-width in update posts. */
.project-image-figure {
  margin: 0.75rem 0 0.85rem;
}

/* Keep single project figure images crisp and aligned to the text column. */
.project-image-figure img {
  display: block;
  width: 100%;
  border: 1px solid var(--banner-border);
}

/* Mark future image locations in project prose without pretending final media is present. */
.project-photo-placeholder {
  display: grid;
  min-height: 8rem;
  place-items: center;
  border: 1px dashed var(--rule);
  margin: 0.75rem 0 0.85rem;
  color: var(--tertiary);
  font-weight: 800;
}

/* Indent numbered explanatory lists without widening the content column. */
.indented-number-list {
  margin: 0.42rem 0 0.72rem 1.25rem;
  padding-left: 1.65rem;
}

/* Keep numbered list items close enough to read as one grouped set. */
.indented-number-list li {
  margin: 0.22rem 0;
}

/* Keep project card descriptions compact. */
.project-card p {
  margin-bottom: 0.55rem;
  color: var(--muted);
  font-size: 0.76rem;
}

/* Use content pages as the same narrow one-column reading surface. */
.content-panel {
  max-width: 52rem;
  margin-inline: auto;
}

/* Give content pages a clear top label. */
.page-kicker {
  margin: 0 0 0.75rem;
  color: var(--red);
  font-weight: 900;
  text-transform: uppercase;
}

/* Show topic aliases as compact hashtag labels at the top of quick-link pages. */
.topic-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.4rem;
  margin: 0.15rem 0 0.75rem;
  padding: 0;
  list-style: none;
}

/* Match topic tags to the highlighted quick-link visual language without making them links. */
.topic-tags li {
  border: 1px solid var(--quick-link-border);
  padding: 0.02rem 0.22rem;
  background: var(--highlight);
  color: var(--secondary);
  font-size: 0.76rem;
  font-weight: 800;
}

/* Let content-page prose reach the same centered column edge as the homepage. */
.content-panel p,
.content-panel li {
  max-width: 100%;
}

/* Compact common prose spacing for the denser personal-site rhythm. */
p,
ul,
ol,
dl {
  margin-top: 0.38rem;
  margin-bottom: 0.55rem;
}

/* Make project anchors visible when jumping from links. */
.anchor-target {
  scroll-margin-top: 1rem;
}

/* Match the intro divider to the thin rules that separate individual project shelves. */
.project-shelf-divider {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 0.34rem 0 0.42rem;
}

/* Space project page entries with simple rules instead of cells. */
.project-entry + .project-entry {
  border-top: 1px solid var(--rule);
  margin-top: 0.95rem;
  padding-top: 0.95rem;
}

/* Size repeated project shelf banners to the wide 1200x200 project-header proportion. */
.project-shelf-banner {
  display: block;
  width: min(100%, 1200px);
  aspect-ratio: 6 / 1;
  border: 1px solid var(--banner-border);
  margin: 0.22rem auto 0.42rem;
  background: transparent;
  object-fit: cover;
}

/* Keep contact links easy to scan. */
.contact-list {
  display: grid;
  gap: 0.35rem;
  padding-left: 1.1rem;
}

/* Contain the floated portrait so the footer rule waits until the contact layout is complete. */
.content-panel.h-card {
  display: flow-root;
}

/* Float the contact portrait inside a transparent banner-colored frame. */
.contact-portrait-frame {
  float: right;
  width: min(38%, 14.75rem);
  margin: -1.35rem 0 0.7rem 1.15rem;
  border: 1px solid var(--banner-border);
  background: transparent;
}

/* Center the recolored transparent portrait within its frame. */
.contact-portrait-frame img {
  display: block;
  width: 100%;
  padding: 0;
  object-fit: contain;
}

/* Invert the white line portrait only in light mode so the drawing remains legible on the pale surface. */
:root[data-theme="light"] .contact-portrait-frame img {
  filter: invert(1) contrast(1.08);
}

/* Stack the contact portrait above prose when the column becomes narrow. */
@media (max-width: 620px) {
  .contact-portrait-frame {
    float: none;
    width: min(100%, 18rem);
    margin: 0.1rem auto 0.75rem;
  }
}

/* Keep the footer in the same centered column as the content. */
.site-footer {
  width: min(var(--measure), calc(100% - 2rem));
  border-top: 1px solid var(--rule);
  margin: 0 auto;
  padding: 0.7rem 0 1.45rem;
  background: transparent;
  color: var(--muted);
  font-size: 0.7rem;
}

/* Remove excess footer paragraph spacing. */
.site-footer p {
  margin: 0.25rem 0;
}

/* Turn the shared footer into the contact destination now that contact is site-wide. */
.site-contact-footer {
  display: grid;
  gap: 0;
}

/* Give the footer credential enough weight to read as the first contact line. */
.footer-credential {
  max-width: 40rem;
  margin-top: -0.08rem;
  color: var(--secondary);
  font-weight: 800;
}

/* Make the contact label read as the footer title without turning it into a card header. */
.footer-contact-title {
  margin-top: 0;
  color: var(--callout-title);
  font-size: 1rem;
  font-weight: 800;
  line-height: 1.2;
}

/* Keep the copyable email visually inline while preserving button accessibility. */
.footer-email-copy {
  justify-self: start;
  margin-top: 0.56rem;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--secondary);
  cursor: pointer;
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
}

/* Highlight only the email label so the line still reads like normal footer text. */
.footer-email-label {
  background: transparent;
  color: var(--callout-title);
  font-weight: 800;
}

/* Keep the obfuscated placeholder address plain until hover, focus, or scroll focus. */
.footer-email-address {
  color: var(--secondary);
  font-weight: 800;
}

/* Share hover, focus, and temporary-scroll-highlight states without adding a box border. */
.footer-email-copy:hover,
.footer-email-copy:focus-visible,
.footer-email-copy.is-highlighted {
  outline: 0;
  text-decoration: underline;
  text-decoration-thickness: 0.11em;
  text-underline-offset: 0.16em;
}

/* Apply the temporary highlight to the text itself instead of drawing a control frame. */
.footer-email-copy:hover .footer-email-label,
.footer-email-copy:hover .footer-email-address,
.footer-email-copy:focus-visible .footer-email-label,
.footer-email-copy:focus-visible .footer-email-address,
.footer-email-copy.is-highlighted .footer-email-label,
.footer-email-copy.is-highlighted .footer-email-address {
  background: transparent;
  color: var(--callout-title);
}

/* Present clipboard feedback as a small pop-up box without moving footer layout. */
.footer-copy-message {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 5;
  border: 1px solid var(--yellow);
  padding: 0.34rem 0.55rem;
  background: var(--paper);
  color: var(--yellow);
  font-weight: 800;
  opacity: 0;
  pointer-events: none;
  transform: translateY(0.4rem);
  transition:
    opacity 160ms ease,
    transform 160ms ease;
}

/* Fade the confirmation in only while the script reports a successful copy attempt. */
.footer-copy-message.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Move the quick-links window into document flow before it would collide with the page. */
@media (max-width: 1120px) {
  body .quick-links-window {
    position: static;
    width: min(var(--glass-width), calc(100% - 1.5rem));
    max-height: 16rem;
    margin: -1rem auto 2rem;
  }

  /* Preserve scrolling behavior after the quick-links window moves below the main column. */
  .quick-links-window-nav {
    max-height: 13.6rem;
  }
}

/* Stack the header cleanly on narrow phones. */
@media (max-width: 620px) {
.content-glass {
    width: min(100% - 0.75rem, var(--glass-width));
    margin-top: 0.6rem;
  }

  .site-header {
    align-items: flex-start;
    flex-direction: column;
  }

  .site-nav {
    justify-content: flex-start;
  }

  /* Stack paired project photos when the page column is narrow. */
  .paired-project-images {
    grid-template-columns: 1fr;
  }

}
