/* ==========================================================================
   mvcprogrammer.com — styles.css
   Mobile-first. Light/dark follows the OS via prefers-color-scheme until the visitor picks one with
   the theme toggle; data-theme on the root then sets color-scheme, and light-dark() follows it.
   ========================================================================== */

/* ---------- Fonts (self-hosted, latin subset, variable weight) ---------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Design tokens ---------- */
:root {
  color-scheme: light dark;

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* JetBrains Rider palette, light UI grays and New UI chrome, with the JetBrains blue accent.
     light-dark() picks the value for the active color scheme. */
  --bg: light-dark(#f7f8fa, #1e1f22);
  --bg-alt: light-dark(#eff1f4, #26282d);
  --surface: light-dark(#ffffff, #2b2d30);
  --text: light-dark(#1e1f22, #dfe1e5);
  --text-muted: light-dark(#5a5d63, #a8adbd);
  --border: light-dark(#dfe1e5, #393b40);
  --accent: light-dark(#2f62d9, #548af7);
  --accent-hover: light-dark(#244fb8, #6f9cff);
  --hover: #ff6f91;
  --hover-soft: rgba(255, 111, 145, 0.14);
  --hover-contrast: #16171a;
  --accent-contrast: light-dark(#ffffff, #16171a);
  --accent-soft: light-dark(rgba(53, 116, 240, 0.10), rgba(84, 138, 247, 0.14));
  --shadow: 0 1px 2px light-dark(rgba(30, 31, 34, 0.06), rgba(0, 0, 0, 0.45)), 0 8px 24px light-dark(rgba(30, 31, 34, 0.06), rgba(0, 0, 0, 0.35));

  --radius: 12px;
  --radius-sm: 8px;
  --container: 72rem;
  --gutter: 1.25rem;
  --header-h: 4rem;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* The theme toggle's choice, saved and applied by theme.js. Without it the root keeps
   color-scheme: light dark and the OS decides. */
:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

/* ---------- Reset & base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem);
  margin-bottom: 1.5rem;
}

h3 {
  font-size: 1.25rem;
}

p {
  margin: 0 0 1rem;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--hover);
  text-decoration: underline;
}

ul, ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

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

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

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
  text-decoration: none;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.icon {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
}

/* ---------- Typography helpers ---------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

.lead {
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
  color: var(--text-muted);
  max-width: 40rem;
  text-wrap: pretty;
}

/* Short paragraph under a section heading, before the cards */
.section-intro {
  color: var(--text-muted);
  max-width: 44rem;
  margin: -0.5rem 0 2rem;
  text-wrap: pretty;
}

/* ---------- Buttons ---------- */
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.2;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.2s var(--ease);
}

.button:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.button-primary {
  background: var(--accent);
  color: var(--accent-contrast);
}

.button-primary:hover {
  background: var(--hover);
  color: var(--hover-contrast);
}

.button-secondary {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}

.button-secondary:hover {
  color: var(--hover);
  border-color: var(--hover);
  background: var(--hover-soft);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

/* ---------- Header & nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg); /* fallback for browsers without color-mix() */
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.site-header.is-scrolled {
  border-bottom-color: var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h);
  gap: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--text);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand:hover {
  text-decoration: none;
}

/* The brand group is the site name plus the edition menu (a pill button naming the edition that is
   open, which drops a list of the four editions) and the theme toggle. On phones those two wrap
   under the name. */
.brand-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.6rem;
  row-gap: 0.2rem;
  min-width: 0;
}

.brand-name {
  white-space: nowrap;
}

/* The edition pill and the theme toggle travel together, so on phones they wrap under the name as a pair. */
.brand-controls {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.edition {
  position: relative;
}

.edition-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.22rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.25;
  white-space: nowrap;
  cursor: pointer;
}

/* A small chevron drawn from two borders; it flips while the list is open. */
.edition-toggle::after {
  content: "";
  width: 0.38rem;
  height: 0.38rem;
  margin-top: -0.2rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.2s var(--ease), margin-top 0.2s var(--ease);
}

.edition-toggle:hover,
.edition-toggle[aria-expanded="true"] {
  color: var(--hover);
  border-color: var(--hover);
  background: var(--hover-soft);
}

.edition-toggle[aria-expanded="true"]::after {
  margin-top: 0.2rem;
  transform: rotate(225deg);
}

.edition-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 1;
  display: none;
  min-width: 11rem;
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

.edition.is-open .edition-menu {
  display: block;
}

.edition-link {
  display: block;
  padding: 0.45rem 0.75rem;
  border-radius: 6px;
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
}

/* Every entry reserves room for the marker so the labels line up; only the open edition shows it. */
.edition-link::before {
  content: "";
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  margin-right: 0.55rem;
  border-radius: 50%;
  vertical-align: middle;
}

.edition-link[aria-current="true"] {
  color: var(--accent);
}

.edition-link[aria-current="true"]::before {
  background: var(--accent);
}

.edition-link:hover,
.edition-link:focus-visible {
  color: var(--hover);
  background: var(--hover-soft);
  text-decoration: none;
}

/* Theme toggle: a round button beside the edition pill. It holds both icons and shows the one for
   the theme a click switches to (the moon while light, the sun while dark), read from the same
   data-theme and prefers-color-scheme the palette follows, so the button keeps no state. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
}

.theme-toggle:hover {
  color: var(--hover);
  border-color: var(--hover);
  background: var(--hover-soft);
}

.theme-toggle .icon {
  width: 0.95rem;
  height: 0.95rem;
}

.theme-icon {
  display: inline-flex;
}

.theme-icon-sun,
:root[data-theme="dark"] .theme-icon-moon {
  display: none;
}

:root[data-theme="dark"] .theme-icon-sun {
  display: inline-flex;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-icon-moon {
    display: none;
  }

  :root:not([data-theme="light"]) .theme-icon-sun {
    display: inline-flex;
  }
}

.brand-mark {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--accent);
}

.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  margin-right: -0.5rem;
  background: none;
  border: 0;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.nav-toggle-bar {
  display: block;
  width: 1.375rem;
  height: 2px;
  margin-inline: auto;
  background: var(--text);
  border-radius: 2px;
  transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.site-nav {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  display: none;
  padding: 0.75rem var(--gutter) 1.25rem;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.site-nav.is-open {
  display: block;
}

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

.nav-link {
  display: block;
  padding: 0.65rem 0.25rem;
  color: var(--text);
  font-weight: 500;
  border-bottom: 1px solid var(--border);
}

.nav-link:hover {
  color: var(--hover);
  text-decoration: none;
}

.nav-link[aria-current="true"] {
  color: var(--accent);
}

.social-list {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.75rem;
}

.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  transition: color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.social-link:hover {
  color: var(--hover);
  background: var(--hover-soft);
}

/* The brand group (site name plus the edition pill) is wider than a name, so the inline nav waits
   for 52em, runs compact until 68em, and between 52em and 64em the social icons stay in the footer
   only. The JavaScript in every edition closes the mobile menu at the same 52em. */
@media (min-width: 52em) {
  .nav-toggle {
    display: none;
  }

  .site-nav {
    position: static;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
  }

  .nav-list {
    flex-direction: row;
    gap: 0.25rem;
  }

  .nav-link {
    position: relative;
    padding: 0.5rem 0.75rem;
    border: 0;
    font-size: 0.9375rem;
  }

  .nav-link::after {
    content: "";
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0.15rem;
    height: 2px;
    background: var(--accent);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.2s var(--ease);
  }

  .nav-link:hover::after,
  .nav-link[aria-current="true"]::after {
    transform: scaleX(1);
  }

  .nav-link:hover::after {
    background: var(--hover);
  }

  .social-list {
    margin: 0;
    padding-left: 1rem;
    border-left: 1px solid var(--border);
  }
}

@media (min-width: 52em) and (max-width: 63.99em) {
  .site-nav .social-list {
    display: none;
  }
}

@media (min-width: 52em) and (max-width: 67.99em) {
  .brand {
    font-size: 0.9375rem;
  }

  .edition-toggle {
    font-size: 0.75rem;
  }

  .site-nav {
    gap: 1rem;
  }

  .nav-link {
    padding: 0.5rem;
    font-size: 0.875rem;
  }
}

/* ---------- Sections ---------- */
.section {
  padding-block: clamp(4rem, 8vw, 7rem);
}

.section-alt {
  background: var(--bg-alt);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
  margin-bottom: 1.5rem;
}

.section-head h2 {
  margin-bottom: 0;
}

.subsection-title {
  margin-top: 3.5rem;
  margin-bottom: 1.25rem;
  font-size: 1.375rem;
}

/* ---------- Hero ---------- */
.hero {
  padding-block: clamp(5rem, 14vw, 10rem) clamp(4rem, 10vw, 7rem);
  border-bottom: 1px solid var(--border);
}

.hero h1 {
  font-size: clamp(2.75rem, 2rem + 5vw, 5.5rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  margin-bottom: 1.25rem;
}

.highlights {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.5rem;
  margin-top: 2.5rem;
}

.highlights li {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.highlight-value {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--text);
  line-height: 1.1;
}

.highlight-label {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* ---------- About ---------- */
.about-grid {
  display: grid;
  gap: 2.5rem;
}

.about-body p {
  max-width: 44rem;
  text-wrap: pretty;
}

.about-body .button {
  margin-top: 1rem;
}

.aside-title {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Second heading in the About aside (Domains) needs room after the skills tags */
.tag-list + .aside-title {
  margin-top: 1.75rem;
}

.tag {
  font-family: var(--font-mono);
  font-size: 0.875rem;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}

/* A tag that links somewhere reads like the others until hovered. */
.tag a {
  color: inherit;
}

.tag a:hover,
.tag a:focus-visible {
  color: var(--hover);
}

/* The hero highlights that have an edition of this site link to it, styled like the chips. */
.highlight-value a {
  color: inherit;
}

.highlight-value a:hover,
.highlight-value a:focus-visible {
  color: var(--hover);
}

@media (min-width: 48em) {
  .about-grid {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 4rem;
  }
}

/* ---------- Quote ---------- */
.quote-band {
  padding-block: clamp(3rem, 6vw, 5rem);
  background: var(--bg-alt);
  border-block: 1px solid var(--border);
}

.quote {
  margin: 0;
  max-width: 52rem;
  margin-inline: auto;
  text-align: center;
}

.quote blockquote {
  margin: 0;
}

.quote blockquote p {
  color: var(--accent);
  font-size: clamp(1.25rem, 1rem + 1.4vw, 1.75rem);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.quote figcaption {
  margin-top: 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--hover);
}

.quote figcaption::before {
  content: "— ";
}

/* Call to action under a card grid */
.section-cta {
  margin-top: 2rem;
}

/* ---------- Cards ---------- */
.card-grid {
  display: grid;
  gap: 1.25rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.card:hover {
  border-color: var(--hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}

.service-card {
  padding: 1.75rem;
}

.service-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-bottom: 1.25rem;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
}

.service-icon .icon {
  width: 1.5rem;
  height: 1.5rem;
}

.service-card h3 {
  margin-bottom: 0.5rem;
}

.service-card p {
  color: var(--text-muted);
  font-size: 1rem;
}

.service-card p + p {
  margin-top: 0.75rem;
}

.card-media {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--border);
}

.card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Shown by main.js when a portfolio image file is missing */
.card-media.is-missing img {
  display: none;
}

.card-media.is-missing::after {
  content: attr(data-label);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  text-align: center;
  background:
    repeating-linear-gradient(135deg, transparent 0 10px, var(--accent-soft) 10px 11px);
}

.card-body {
  padding: 1.25rem 1.5rem 1.5rem;
}

.card-body h3 {
  font-size: 1.125rem;
  margin-bottom: 0.25rem;
}

.card-subtitle {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

.card-subtitle:last-child {
  margin-bottom: 0;
}

.card-body > p:not(.card-subtitle) {
  color: var(--text-muted);
  font-size: 0.9375rem;
}

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

.card-tags .tag {
  font-size: 0.8125rem;
  padding: 0.3rem 0.65rem;
  background: var(--bg-alt);
}

.card-link {
  display: inline-block;
  margin-top: 1rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.card-link:hover,
.card-link:focus-visible {
  color: var(--hover);
  border-bottom-color: currentColor;
}

.card-link + .card-link {
  margin-left: 1.25rem;
}

.card-link::after {
  content: " \2197";
}

/* The secondary links under a card's button: one row, never wrapping, with the gap doing the
   spacing the adjacent-link margin does elsewhere. */
.card-links {
  display: flex;
  flex-wrap: nowrap;
  gap: 1.25rem;
  margin-top: 0.75rem;
  white-space: nowrap;
}

.card-links .card-link {
  margin-top: 0;
}

.card-links .card-link + .card-link {
  margin-left: 0;
}

@media (min-width: 40em) {
  .card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* The "under the hood" card spans the grid with its image beside the text */
  .portfolio-card-featured {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  .portfolio-card-featured .card-media {
    aspect-ratio: auto;
    min-height: 16rem;
    border-bottom: 0;
    border-right: 1px solid var(--border);
  }

  /* The featured photo has its subject on the right; keep it in frame when the text column sets the height */
  .portfolio-card-featured .card-media img {
    object-position: 72% center;
  }

  .portfolio-card-featured .card-body {
    align-self: center;
    padding: 2rem;
  }
}

@media (min-width: 64em) {
  .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.5rem;
  }

  /* Three project cards sit in one row under the full-width featured card; the FHIR API card
     takes the whole row while its explorer is open (see the FHIR block). */
  .portfolio-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- Timeline ---------- */
.timeline {
  position: relative;
  padding-left: 1.75rem;
  border-left: 2px solid var(--border);
}

.timeline-item {
  position: relative;
  padding-bottom: 2.5rem;
}

.timeline-item:last-child {
  padding-bottom: 0;
}

.timeline-item::before {
  content: "";
  position: absolute;
  left: calc(-1.75rem - 7px);
  top: 0.45rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--accent);
}

.timeline-date {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin-bottom: 0.35rem;
}

.timeline-item h3,
.timeline-item h4 {
  font-size: 1.125rem;
  margin-bottom: 0.15rem;
}

.timeline-org {
  color: var(--accent);
  font-weight: 500;
  margin-bottom: 0.75rem;
}

.timeline-points {
  display: grid;
  gap: 0.35rem;
  max-width: 44rem;
  color: var(--text-muted);
  list-style: disc;
  padding-left: 1.25rem;
}

.timeline-compact .timeline-item {
  padding-bottom: 1.5rem;
}

.timeline-compact .timeline-org {
  margin-bottom: 0;
}

@media (min-width: 48em) {
  .timeline {
    padding-left: 2.5rem;
  }

  .timeline-item::before {
    left: calc(-2.5rem - 7px);
  }
}

/* ---------- Experience skill filter ----------
   Hidden in the HTML; main.js reveals it once the Experience API has answered. */
.skill-filter {
  margin: -0.25rem 0 1.75rem;
}

.skill-filter-label {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin-bottom: 0.6rem;
}

.skill-filter-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.skill-chip {
  font: inherit;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.2;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}

.skill-chip:hover {
  color: var(--hover);
  border-color: var(--hover);
  background: var(--hover-soft);
}

.skill-chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.skill-chip-more {
  color: var(--text-muted);
  border-style: dashed;
}

.skill-filter-status {
  margin-top: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.timeline.is-loading {
  opacity: 0.55;
  transition: opacity 0.2s var(--ease);
}

/* ---------- Live demo dialogs (the kiosk and the patient explorer) ---------- */
.card-actions {
  margin-top: 1.25rem;
}

.demo-dialog {
  width: min(96vw, 100rem);
  max-width: none;
  max-height: 96vh;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
}

.demo-dialog::backdrop {
  background: rgba(10, 11, 13, 0.72);
}

.demo-dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 1.5rem 1rem;
}

.demo-dialog-head h2 {
  font-size: 1.25rem;
  margin-bottom: 0.35rem;
}

.demo-dialog-note {
  color: var(--text-muted);
  font-size: 0.9375rem;
  max-width: 60rem;
}

.demo-dialog-close {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.demo-dialog-close:hover {
  color: var(--hover);
  border-color: var(--hover);
  background: var(--hover-soft);
}

/* 16:9 when there is room, otherwise capped so the dialog fits the window. The kiosk scales
   itself to whatever box it gets and letterboxes the rest, so the shape does not need to be exact. */
.demo-frame-slot {
  height: min(calc(min(96vw, 100rem) * 9 / 16), 68vh);
  background: #1d1d1d;
}

/* A tall frame for a page that scrolls, such as the patient explorer: as much of the window as the head and foot leave. */
.demo-dialog[data-frame="tall"] .demo-frame-slot {
  height: 76vh;
  background: var(--bg);
}

.demo-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.demo-dialog-foot {
  padding: 0.75rem 1.5rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ---------- Contact ---------- */
.contact-form {
  position: relative;
  display: grid;
  gap: 1.25rem;
  max-width: 44rem;
  margin-top: 2rem;
  padding: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.form-row {
  display: grid;
  gap: 1.25rem;
}

.field {
  display: grid;
  gap: 0.5rem;
}

.field[hidden] {
  display: none;
}

.field-label {
  font-size: 0.875rem;
  font-weight: 600;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 2.875rem;
  padding: 0.65rem 0.9rem;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.field textarea {
  min-height: 9rem;
  resize: vertical;
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Honeypot: off-screen for people, present in the DOM for bots */
.field-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  min-height: 1.5em;
  margin: 0;
  font-size: 0.9375rem;
  color: var(--text-muted);
}

.form-status.is-ok {
  color: var(--accent);
  font-weight: 500;
}

.form-status.is-error {
  color: light-dark(#b91c1c, #fca5a5);
}

.contact-form .button {
  justify-self: start;
}

.contact-form.is-sent .field,
.contact-form.is-sent .button {
  display: none;
}

@media (min-width: 40em) {
  .form-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------- Colophon ----------
   A footnote after Contact: tighter and quieter than the numbered sections above it. */
.colophon {
  padding-block: clamp(3rem, 6vw, 5rem);
}

.colophon h2 {
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.75rem);
  margin-bottom: 1.25rem;
}

.colophon .section-intro {
  font-size: 0.9375rem;
  margin-bottom: 1.5rem;
}

.colophon-list {
  margin: 0 0 0.5rem;
  border-bottom: 1px solid var(--border);
}

.colophon-item {
  display: grid;
  gap: 0.35rem;
  padding-block: 1rem;
  border-top: 1px solid var(--border);
}

.colophon-item dt {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
}

.colophon-item dd {
  margin: 0;
  max-width: 48rem;
  font-size: 0.9375rem;
  color: var(--text-muted);
  text-wrap: pretty;
}

.colophon code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  color: var(--text);
}

@media (min-width: 48em) {
  .colophon-item {
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 2rem;
    align-items: baseline;
  }
}

/* ---------- Footer ---------- */
.site-footer {
  padding-block: 2rem;
  border-top: 1px solid var(--border);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.footer-copy {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin: 0;
}

.site-footer .social-list {
  margin: 0;
}

.footer-links {
  display: flex;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.footer-links a {
  color: var(--text-muted);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--hover);
  text-decoration: underline;
}

/* ---------- Legal pages (privacy.html, terms.html) ---------- */
.legal-page .site-header {
  position: sticky;
}

.legal {
  padding-top: calc(var(--header-h) + clamp(3rem, 6vw, 5rem));
}

.legal-inner {
  max-width: 44rem;
}

.legal h1 {
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  margin-bottom: 0.5rem;
}

.legal-meta {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin-bottom: 2rem;
}

.legal h2 {
  font-size: 1.375rem;
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
}

.legal ul {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
}

.legal li {
  margin-bottom: 0.35rem;
}

.sms-sample {
  display: block;
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* ---------- FHIR explorer (fhir.mvcprogrammer.com; this file is copied into that app) ----------
   The patient explorer page: search form, a two-column result area that stacks on phones, the
   summary card with its avatar, tiles, pills, and vitals table, and the terminal-style log. The
   editions' FHIR API card no longer holds it, only the demo dialog that frames it. */
.fhir-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-bottom: 1rem;
}

.fhir-title {
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.75rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0;
}

/* The synthetic-data badge: a pill with a pulsing dot, so nobody mistakes this for a real record. */
.fhir-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.4rem 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 999px;
  white-space: nowrap;
}

.fhir-badge-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  animation: fhir-pulse 2.4s var(--ease) infinite;
}

@keyframes fhir-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.fhir-lead {
  margin-bottom: 1.5rem;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* ----- Search ----- */
.fhir-search {
  display: grid;
  gap: 0.75rem;
  padding: 1.25rem 1.5rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.fhir-search-row {
  display: grid;
  gap: 1rem;
}

.fhir-search .field {
  gap: 0.4rem;
}

.fhir-search-action {
  align-self: end;
}

.fhir-search-action .button {
  width: 100%;
  justify-content: center;
  min-height: 2.875rem;
}

.fhir-required {
  color: var(--accent);
}

.fhir-optional {
  font-weight: 400;
  color: var(--text-muted);
}

.field-error {
  min-height: 1.2em;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: #b91c1c;
}

.field input.is-invalid {
  border-color: #b91c1c;
}

.fhir-search .form-status {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.fhir-search .form-status code {
  color: var(--text);
}

.fhir-search.is-loading {
  opacity: 0.7;
}

/* ----- Results ----- */
.fhir-results {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.5rem;
}

.fhir-panel {
  padding: 1.25rem 1.5rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-width: 0;
}

.fhir-panel-title {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.fhir-count {
  text-transform: none;
  letter-spacing: 0;
}

.fhir-empty {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--text-muted);
  text-wrap: pretty;
}

.fhir-empty-inline {
  font-size: 0.9375rem;
  color: var(--text-muted);
}

.fhir-patients {
  display: grid;
  gap: 0.5rem;
  max-height: 32rem;
  overflow-y: auto;
  padding-right: 0.25rem;
}

.fhir-patient {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.6rem 0.75rem;
  font: inherit;
  text-align: left;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.fhir-patient:hover {
  border-color: var(--hover);
  background: var(--hover-soft);
}

.fhir-patient[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.fhir-patient-text {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.fhir-patient-name {
  font-weight: 600;
  line-height: 1.3;
}

.fhir-patient-sub {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* ----- Avatar: eight hues keyed by a hash of the patient id, readable in both themes ----- */
.fhir-avatar {
  --fhir-hue: 215;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 3.25rem;
  height: 3.25rem;
  font-family: var(--font-mono);
  font-size: 1.125rem;
  font-weight: 600;
  border-radius: 50%;
  color: light-dark(hsl(var(--fhir-hue) 55% 28%), hsl(var(--fhir-hue) 60% 84%));
  background: light-dark(hsl(var(--fhir-hue) 60% 88%), hsl(var(--fhir-hue) 35% 26%));
}

.fhir-avatar-sm {
  width: 2.25rem;
  height: 2.25rem;
  font-size: 0.8125rem;
}

.fhir-avatar-0 { --fhir-hue: 215; }
.fhir-avatar-1 { --fhir-hue: 160; }
.fhir-avatar-2 { --fhir-hue: 25; }
.fhir-avatar-3 { --fhir-hue: 280; }
.fhir-avatar-4 { --fhir-hue: 340; }
.fhir-avatar-5 { --fhir-hue: 190; }
.fhir-avatar-6 { --fhir-hue: 55; }
.fhir-avatar-7 { --fhir-hue: 120; }

/* ----- Summary card ----- */
.fhir-summary.is-loading {
  opacity: 0.55;
  transition: opacity 0.2s var(--ease);
}

.fhir-card-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.fhir-card-name {
  font-size: 1.375rem;
  margin-bottom: 0.2rem;
}

.fhir-card-meta {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.fhir-card-meta code {
  color: var(--text);
}

.fhir-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
  margin: 0 0 1.5rem;
}

.fhir-tile {
  padding: 0.75rem 0.9rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.fhir-tile dt {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.fhir-tile dd {
  margin: 0.15rem 0 0;
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--text);
}

.fhir-subtitle {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.6rem;
}

.fhir-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.fhir-pills-resolved {
  margin-top: -1rem;
}

/* The flex display above would beat the hidden attribute; this keeps hidden meaning hidden. */
.fhir-pills[hidden] {
  display: none;
}

/* Two lines: the condition, then its code underneath in the small mono face. */
.fhir-pill {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  max-width: 100%;
  padding: 0.4rem 0.85rem;
  font-size: 0.875rem;
  line-height: 1.3;
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 1rem;
}

.fhir-pill-text {
  overflow-wrap: anywhere;
}

.fhir-pill-code {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.fhir-pill.is-resolved {
  border-color: var(--border);
  border-style: dashed;
  color: var(--text-muted);
}

.fhir-pill-more {
  padding: 0;
  border-style: dashed;
  border-color: var(--border);
}

.fhir-pill-button {
  padding: 0.35rem 0.75rem;
  font: inherit;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
}

.fhir-pill-button:hover {
  color: var(--hover);
}

.fhir-table-wrap {
  overflow-x: auto;
}

.fhir-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.fhir-table th,
.fhir-table td {
  padding: 0.5rem 0.6rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}

.fhir-table th {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.fhir-table-date {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.fhir-table-value {
  font-family: var(--font-mono);
  white-space: nowrap;
}

.fhir-table-time::before {
  content: " ";
}

@media (max-width: 39.99em) {
  .fhir-table-time::before {
    content: none;
  }
}

.fhir-loinc {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--text-muted);
}

/* ----- Under the hood ----- */
.fhir-hood {
  margin-top: 1.5rem;
}

.fhir-hood-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-bottom: 0.75rem;
}

.fhir-hood-head .fhir-panel-title {
  margin-bottom: 0;
}

.fhir-hood-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.25rem;
}

.fhir-hood-actions .card-link {
  margin: 0;
}

.fhir-hood-button {
  padding: 0.45rem 0.9rem;
  font-size: 0.8125rem;
}

.fhir-hood-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* The log reads like a terminal in both themes: dark surface, light mono text, coloured prefixes. */
.fhir-log {
  margin: 0;
  padding: 1rem 1.25rem;
  max-height: 24rem;
  overflow: auto;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: #dfe1e5;
  background: light-dark(#1e1f22, #141517);
  border: 1px solid light-dark(#2b2d30, #393b40);
  border-radius: var(--radius-sm);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.fhir-log-request { color: #8ab4ff; }
.fhir-log-response { color: #9be39b; }
.fhir-log-upstream { color: #f4c56b; }
.fhir-log-detail { color: #a8adbd; }
.fhir-log-note { color: #c8b6ff; }
.fhir-log-error { color: #ff8a8a; }

.fhir-dto {
  margin-top: 0.75rem;
}

.fhir-dto summary {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-muted);
  cursor: pointer;
}

.fhir-dto summary:hover {
  color: var(--hover);
}

.fhir-dto-body,
.fhir-raw {
  margin-top: 0.75rem;
  max-height: 32rem;
}

/* The explorer stands on its own page at fhir.mvcprogrammer.com; these rules travel there with the copy of this file. */
.fhir-explorer {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

/* Phones: the vitals table has no room for a fixed date column, so dates and values may wrap. */
@media (max-width: 39.99em) {
  .fhir-table {
    font-size: 0.875rem;
  }

  .fhir-table th,
  .fhir-table td {
    padding: 0.45rem 0.4rem;
  }

  .fhir-table-value {
    white-space: normal;
  }

  /* The date keeps one line; the time drops under it. */
  .fhir-table-date {
    font-size: 0.75rem;
  }

  .fhir-table-time {
    display: block;
  }
}

@media (min-width: 40em) {
  .fhir-search-row {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) auto;
  }

  .fhir-search-action .button {
    width: auto;
  }
}

@media (min-width: 48em) {
  .fhir-results {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.8fr);
    align-items: start;
    gap: 1.5rem;
  }
}
