/* Generated by scripts/gen_chroma_css.py (github + github-dark) - do not edit by hand. */

/* Background */ .bg { background-color:light-dark(#f7f7f7,#0d1117);color:light-dark(#1f2328,#e6edf3) }
/* PreWrapper */ .chroma { background-color:light-dark(#f7f7f7,#0d1117);-webkit-text-size-adjust:none;color:light-dark(#1f2328,#e6edf3) }
/* Error */ .chroma .err { color:light-dark(#f6f8fa,#f85149);background-color:light-dark(#82071e,transparent) }
/* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit }
/* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0 }
/* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0 }
/* LineHighlight */ .chroma .hl { background-color:light-dark(#dedede,#6e7681) }
/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:light-dark(#7f7f7f,#737679) }
/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:light-dark(#7f7f7f,#6e7681) }
/* Line */ .chroma .line { display:flex }
/* Keyword */ .chroma .k { color:light-dark(#cf222e,#ff7b72) }
/* KeywordConstant */ .chroma .kc { color:light-dark(#cf222e,#79c0ff) }
/* KeywordDeclaration */ .chroma .kd { color:light-dark(#cf222e,#ff7b72) }
/* KeywordNamespace */ .chroma .kn { color:light-dark(#cf222e,#ff7b72) }
/* KeywordPseudo */ .chroma .kp { color:light-dark(#cf222e,#79c0ff) }
/* KeywordReserved */ .chroma .kr { color:light-dark(#cf222e,#ff7b72) }
/* KeywordType */ .chroma .kt { color:light-dark(#cf222e,#ff7b72) }
/* NameAttribute */ .chroma .na { color:light-dark(#1f2328,#e6edf3) }
/* NameClass */ .chroma .nc { color:light-dark(#1f2328,#f0883e) }
/* NameConstant */ .chroma .no { color:light-dark(#0550ae,#79c0ff) }
/* NameDecorator */ .chroma .nd { color:light-dark(#0550ae,#d2a8ff) }
/* NameEntity */ .chroma .ni { color:light-dark(#6639ba,#ffa657) }
/* NameLabel */ .chroma .nl { color:light-dark(#900,#79c0ff);font-weight:bold }
/* NameNamespace */ .chroma .nn { color:light-dark(#24292e,#ff7b72) }
/* NameOther */ .chroma .nx { color:light-dark(#1f2328,#e6edf3) }
/* NameTag */ .chroma .nt { color:light-dark(#0550ae,#7ee787) }
/* NameBuiltin */ .chroma .nb { color:light-dark(#6639ba,#e6edf3) }
/* NameBuiltinPseudo */ .chroma .bp { color:light-dark(#6a737d,#e6edf3) }
/* NameVariable */ .chroma .nv { color:light-dark(#953800,#79c0ff) }
/* NameVariableClass */ .chroma .vc { color:light-dark(#953800,#79c0ff) }
/* NameVariableGlobal */ .chroma .vg { color:light-dark(#953800,#79c0ff) }
/* NameVariableInstance */ .chroma .vi { color:light-dark(#953800,#79c0ff) }
/* NameVariableMagic */ .chroma .vm { color:light-dark(#953800,#79c0ff) }
/* NameFunction */ .chroma .nf { color:light-dark(#6639ba,#d2a8ff) }
/* NameFunctionMagic */ .chroma .fm { color:light-dark(#6639ba,#d2a8ff) }
/* LiteralString */ .chroma .s { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringAffix */ .chroma .sa { color:light-dark(#0a3069,#79c0ff) }
/* LiteralStringBacktick */ .chroma .sb { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringChar */ .chroma .sc { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringDelimiter */ .chroma .dl { color:light-dark(#0a3069,#79c0ff) }
/* LiteralStringDoc */ .chroma .sd { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringDouble */ .chroma .s2 { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringEscape */ .chroma .se { color:light-dark(#0a3069,#79c0ff) }
/* LiteralStringHeredoc */ .chroma .sh { color:light-dark(#0a3069,#79c0ff) }
/* LiteralStringInterpol */ .chroma .si { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringOther */ .chroma .sx { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringRegex */ .chroma .sr { color:light-dark(#0a3069,#79c0ff) }
/* LiteralStringSingle */ .chroma .s1 { color:light-dark(#0a3069,#a5d6ff) }
/* LiteralStringSymbol */ .chroma .ss { color:light-dark(#032f62,#a5d6ff) }
/* LiteralNumber */ .chroma .m { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberBin */ .chroma .mb { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberFloat */ .chroma .mf { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberHex */ .chroma .mh { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberInteger */ .chroma .mi { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberIntegerLong */ .chroma .il { color:light-dark(#0550ae,#a5d6ff) }
/* LiteralNumberOct */ .chroma .mo { color:light-dark(#0550ae,#a5d6ff) }
/* Operator */ .chroma .o { color:light-dark(#0550ae,#ff7b72) }
/* OperatorWord */ .chroma .ow { color:light-dark(#0550ae,#ff7b72) }
/* Punctuation */ .chroma .p { color:light-dark(#1f2328,#e6edf3) }
/* Comment */ .chroma .c { color:light-dark(#57606a,#8b949e) }
/* CommentHashbang */ .chroma .ch { color:light-dark(#57606a,#8b949e) }
/* CommentMultiline */ .chroma .cm { color:light-dark(#57606a,#8b949e) }
/* CommentSingle */ .chroma .c1 { color:light-dark(#57606a,#8b949e) }
/* CommentSpecial */ .chroma .cs { color:light-dark(#57606a,#8b949e) }
/* CommentPreproc */ .chroma .cp { color:light-dark(#57606a,#8b949e) }
/* CommentPreprocFile */ .chroma .cpf { color:light-dark(#57606a,#8b949e) }
/* GenericDeleted */ .chroma .gd { color:light-dark(#82071e,#ffa198);background-color:light-dark(#ffebe9,#490202) }
/* GenericEmph */ .chroma .ge { color:light-dark(#1f2328,#e6edf3) }
/* GenericInserted */ .chroma .gi { color:light-dark(#116329,#56d364);background-color:light-dark(#dafbe1,#0f5323) }
/* GenericOutput */ .chroma .go { color:light-dark(#1f2328,#8b949e) }
/* GenericUnderline */ .chroma .gl { text-decoration:underline }
/* TextWhitespace */ .chroma .w { color:light-dark(#fff,#6e7681) }
/* NameException */ .chroma .ne { color:light-dark(#1f2328,#f0883e) }
/* NameProperty */ .chroma .py { color:light-dark(#1f2328,#79c0ff) }
/* Literal */ .chroma .l { color:light-dark(#1f2328,#a5d6ff) }
/* LiteralDate */ .chroma .ld { color:light-dark(#1f2328,#79c0ff) }
/* GenericError */ .chroma .gr { color:light-dark(#1f2328,#ffa198) }
/* GenericHeading */ .chroma .gh { color:light-dark(#1f2328,#79c0ff) }
/* GenericPrompt */ .chroma .gp { color:light-dark(#1f2328,#8b949e) }
/* GenericSubheading */ .chroma .gu { color:light-dark(#1f2328,#79c0ff) }
/* GenericTraceback */ .chroma .gt { color:light-dark(#1f2328,#ff7b72) }
:root {
  /* Brand palette (raw values). */
  --color-edgj-light-blue: rgb(0, 92, 151);
  --color-edgj-navy: rgb(14, 23, 38);
  --color-overlay-bg: rgba(59, 68, 75, 0.5);
  --color-text-light: #ffffff;

  /* Semantic tokens. Each resolves via light-dark() against the active
     color-scheme, so the whole palette flips with no JavaScript. */
  --color-bg: light-dark(#ffffff, #14181d);
  --color-text: light-dark(#1c1e21, #d7dade);
  --color-muted: light-dark(#555555, #9aa1a9);
  --color-accent: light-dark(var(--color-edgj-light-blue), rgb(125, 180, 226));
  --color-border: var(--color-accent);
  --color-surface: light-dark(#f3f5f7, #1e242b);

  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  color-scheme: light dark;
  interpolate-size: allow-keywords;
}

/* The header checkbox (no JavaScript) forces the scheme *opposite* to the
   system preference; unchecked means "follow the system". light-dark()
   tokens and form controls all flip with it. State is per-page: a static
   site has nowhere to persist it without JS or a server-set cookie. */
@media (prefers-color-scheme: light) {
  html:has(.theme-toggle-input:checked) {
    color-scheme: dark;
  }
}
@media (prefers-color-scheme: dark) {
  html:has(.theme-toggle-input:checked) {
    color-scheme: light;
  }
}

body {
  font-family: "IBM Plex Sans", Verdana, Geneva, Tahoma, sans-serif;
  line-height: 1.6;
  /* Comfortable reading measure; figures may break out wider (see
     .photo-container and .photo-page). */
  max-width: 72ch;
  margin-inline: auto;
  padding-inline: 1rem;
  background-color: var(--color-bg);
  color: var(--color-text);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  /* Real SemiBold glyphs (woff2 below) instead of synthesized bold. */
  font-weight: 600;
  text-wrap: balance;
}

b,
strong,
th {
  font-weight: 600;
}

p,
li,
figcaption {
  text-wrap: pretty;
}

:is(h1, h2, h3, h4, h5, h6)[id] {
  scroll-margin-block-start: 1rem;
}

a {
  color: var(--color-accent);
}

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

/* || Inline code and keys */

code {
  font-family: var(--font-mono);
}

:not(pre) > code {
  font-size: 0.9em;
  padding: 0.1em 0.35em;
  border-radius: 3px;
  background-color: var(--color-surface);
}

kbd {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 0.05em 0.4em;
  border: 1px solid var(--color-muted);
  border-block-end-width: 2px;
  border-radius: 3px;
  background-color: var(--color-surface);
}

/* || Blockquotes and GitHub-style alerts */

blockquote {
  margin-inline: 0;
  padding-inline-start: 1rem;
  border-inline-start: 3px solid var(--color-border);
  color: var(--color-muted);
}

blockquote.alert {
  --alert-accent: var(--color-accent);
  padding-block: 0.5rem;
  padding-inline-end: 1rem;
  border-inline-start-color: var(--alert-accent);
  border-radius: 0 4px 4px 0;
  background-color: color-mix(in srgb, var(--alert-accent) 7%, transparent);
  color: var(--color-text);
}

blockquote.alert > :last-child {
  margin-block-end: 0;
}

.alert-heading {
  margin-block: 0 0.4rem;
  font-weight: 600;
  color: var(--alert-accent);
}

.alert-tip {
  --alert-accent: light-dark(#1a7f37, #3fb950);
}

.alert-warning {
  --alert-accent: light-dark(#9a6700, #d29922);
}

.alert-caution {
  --alert-accent: light-dark(#cf222e, #f85149);
}

article {
  text-align: start;
}

article header p {
  font-size: smaller;
}

body > header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1.2rem;
  margin-block: 1.5rem;
  border-block-end: 1px solid var(--color-border);
}

.site-title {
  margin: 0;
  font-size: 1.3rem;
}

/* The site-title emoji doubles as the dark-mode toggle: a label for the
   visually-hidden checkbox at the top of <header>. */
.theme-toggle {
  cursor: pointer;
}

.theme-toggle-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.theme-toggle-input:focus-visible ~ .site-title .theme-toggle {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Show the circle matching the page's *current* scheme: ⚪ when light is
   active, ⚫ when dark is active (mirrors the color-scheme rules above). */
.theme-toggle-emoji::before {
  content: "⚪";
}
@media (prefers-color-scheme: light) {
  html:has(.theme-toggle-input:checked) .theme-toggle-emoji::before {
    content: "⚫";
  }
}
@media (prefers-color-scheme: dark) {
  html:not(:has(.theme-toggle-input:checked)) .theme-toggle-emoji::before {
    content: "⚫";
  }
}

nav ul {
  display: flex;
  list-style: none;
  padding: 0;
  flex-wrap: wrap;
  margin: 0;
  font-size: 1.3rem;
  gap: 0.4rem 1.2rem;
}

body > header nav a {
  text-decoration: none;
}

body > header nav a:hover {
  text-decoration: underline;
}

body > header nav a[aria-current="page"] {
  border-block-end: 2px solid var(--color-accent);
}

footer {
  font-size: smaller;
  text-align: center;
  margin-block: 1.5rem;
  padding-block-start: 0.5rem;
  border-block-start: 1px solid var(--color-border);
}

footer ul {
  display: flex;
  list-style: none;
  justify-content: center;
  padding: 0;
  flex-wrap: wrap;
  font-size: 1.3rem;
  column-gap: 1.875rem;
}

footer a {
  text-decoration: none;
}

/* The CC and RSS icons are monochrome SVGs loaded via <img>, so they render
   in their own document context where currentColor resolves to black. Invert
   them when the effective scheme is dark so they stay legible. Mastodon and
   Signal logos are intentionally untouched — they're brand-coloured. */
@media (prefers-color-scheme: dark) {
  html:not(:has(.theme-toggle-input:checked)) footer img[src^="/icons/cc"],
  html:not(:has(.theme-toggle-input:checked)) footer img[src="/icons/rss.svg"] {
    filter: invert(1);
  }
}
@media (prefers-color-scheme: light) {
  html:has(.theme-toggle-input:checked) footer img[src^="/icons/cc"],
  html:has(.theme-toggle-input:checked) footer img[src="/icons/rss.svg"] {
    filter: invert(1);
  }
}

.build-info {
  max-inline-size: 32rem;
  margin: 1.75rem auto 0;
  text-align: start;
  border: 1px solid var(--color-accent);
  border-radius: 4px;
}

.build-info > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--color-accent);
  width: max-content;
  margin: -0.75em auto 0;
  padding: 0 0.6rem;
  background: var(--color-bg);
  list-style: none;
}

.build-info > summary::-webkit-details-marker,
.build-info > summary::marker {
  display: none;
  content: "";
}

.build-info::details-content {
  block-size: 0;
  opacity: 0;
  overflow: clip;
  transition: content-visibility 1s ease allow-discrete,
              block-size 1s ease,
              opacity 0.8s ease;
}

.build-info[open]::details-content {
  block-size: auto;
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .build-info::details-content {
    transition: none;
  }
}

.build-info-card {
  margin-block-start: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.85em;
}

.build-info-card section {
  padding: 0.6rem 1rem;
  border-block-end: 1px dashed color-mix(in srgb, var(--color-accent) 30%, transparent);
}

.build-info-card section:last-child {
  border-block-end: none;
}

.build-info-card h2 {
  margin: 0 0 0.3rem;
  font-size: 0.75em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-accent);
  opacity: 0.75;
}

.build-info-card dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 1.25rem;
  margin: 0;
}

.build-info-card dt {
  font-weight: 600;
  color: var(--color-accent);
}

.build-info-card dd {
  margin: 0;
  word-break: break-word;
}

.build-info-card .session-info {
  display: block;
  inline-size: 100%;
  max-inline-size: 21rem;
  height: auto;
  margin-block-start: 0.1rem;
}

.build-info-card .build-verify {
  background: color-mix(in srgb, var(--color-accent) 6%, transparent);
}

.build-info-card .build-verify > details > summary {
  cursor: pointer;
  margin: 0 0 0.3rem;
  font-size: 0.75em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-accent);
  opacity: 0.75;
  list-style: revert;
}

.build-info-card .build-verify > details::details-content {
  block-size: 0;
  opacity: 0;
  overflow: clip;
  transition: content-visibility 1s ease allow-discrete,
              block-size 1s ease,
              opacity 0.8s ease;
}

.build-info-card .build-verify > details[open]::details-content {
  block-size: auto;
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .build-info-card .build-verify > details::details-content {
    transition: none;
  }
}

.build-info-card .build-verify p {
  margin: 0 0 0.4rem;
}

.build-info-card .build-verify pre {
  margin: 0;
  padding: 0.5rem 0.6rem;
  background: var(--color-edgj-navy);
  color: var(--color-text-light);
  border-radius: 3px;
  overflow-x: auto;
  font-size: 0.95em;
  line-height: 1.4;
}

/* Scoped to prose so the icon can't dangle after a link-wrapped image. */
main :is(p, li, figcaption) a[href^='http']::after {
  content: "";
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  margin-inline-start: 0.3em;
  vertical-align: middle;
  background-color: currentColor;
  /* SVG for the mask - paths will default to black, forming the shape */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.5 2h-3a.5.5 0 0 0 0 1h1.8L7.65 7.65a.5.5 0 0 0 .7.7L13 3.7v1.8a.5.5 0 0 0 1 0v-3a.5.5 0 0 0-.5-.5Z'/%3E%3Cpath d='M12 11a.5.5 0 0 0-.5.5v1.5H4V5h1.5a.5.5 0 0 0 0-1H3.5A.5.5 0 0 0 3 4.5v9a.5.5 0 0 0 .5.5h9a.5.5 0 0 0 .5-.5V11.5A.5.5 0 0 0 12 11Z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.5 2h-3a.5.5 0 0 0 0 1h1.8L7.65 7.65a.5.5 0 0 0 .7.7L13 3.7v1.8a.5.5 0 0 0 1 0v-3a.5.5 0 0 0-.5-.5Z'/%3E%3Cpath d='M12 11a.5.5 0 0 0-.5.5v1.5H4V5h1.5a.5.5 0 0 0 0-1H3.5A.5.5 0 0 0 3 4.5v9a.5.5 0 0 0 .5.5h9a.5.5 0 0 0 .5-.5V11.5A.5.5 0 0 0 12 11Z'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* Link that wraps a clickable image (navigates to the full-screen photo page). */
.photo-trigger {
  display: block;
  cursor: zoom-in;
}
.photo-trigger:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

@font-face {
  font-display: swap;
  font-family: "IBM Plex Sans";
  font-weight: 400;
  src: url("/fonts/ibm-plex-sans-v14-latin-regular.woff2") format("woff2");
}

@font-face {
  font-display: swap;
  font-family: "IBM Plex Sans";
  font-weight: 600;
  src: url("/fonts/ibm-plex-sans-semibold-latin1.woff2") format("woff2");
  unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-00FF, U+0131,
    U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A,
    U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC,
    U+2122, U+2212, U+FB01-FB02;
}

h1 {
  text-align: center;
  margin-block: 0.67em;
  font-size: 2em;
}

.post-metadata {
  opacity: 0.4;
  text-align: center;
  font-style: italic;
}

.content p {
  text-align: start;
}

ol.posts-toc-index {
  list-style-type: square;
}

ol.posts-toc {
  list-style-type: none;
}

/* || Photo Overlay */

.photo-container {
  position: relative;
  display: block;
  /* Photos are first-class: shrink to the image but allow breaking out of
     the 72ch text column, up to 56rem. left + translateX centres the figure
     even when it is wider than its container (auto margins can't). The
     extra rem of slack keeps wide figures clear of the scrollbar, which
     100vw includes. */
  width: fit-content;
  max-width: min(56rem, calc(100vw - 3rem));
  margin-block: 2.5rem;
  margin-inline: 0;
  left: 50%;
  transform: translateX(-50%);
}

.photo-container img {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 6px;
}

.photo-caption-overlay {
  border-radius: 0 0 6px 6px;
}

/* || Photo Gallery (CSS grid of figure-overlay tiles, no JavaScript) */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  gap: 0.75rem;
  width: min(56rem, calc(100vw - 3rem));
  margin-block: 2.5rem;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}

/* Tiles fill their grid cell; undo the standalone-figure breakout. */
.gallery .photo-container {
  width: auto;
  max-width: none;
  margin: 0;
  left: auto;
  transform: none;
}

/* Uniform tiles: equal-width columns and a fixed crop ratio. */
.gallery .photo-container img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.photo-caption-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  max-height: 60%;
  overflow-y: auto;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 0.5em 1em;
  text-align: center;
  font-size: 0.9em;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.3s ease-in-out,
    visibility 0.3s ease-in-out;
}
.photo-caption-overlay a {
  color: white;
  text-decoration: none;
}
.photo-caption-overlay a:hover {
  text-decoration: underline;
}
/* Only hover-capable devices reveal overlays on hover/focus. (Gating focus-within to
   these devices also prevents the overlays re-appearing on touch when focus returns to
   the trigger button after the lightbox closes.) */
@media (hover: hover) {
  .photo-container:hover .photo-caption-overlay,
  .photo-container:focus-within .photo-caption-overlay {
    opacity: 1;
    visibility: visible;
  }
}

.photo-caption-below {
  padding: 0.5em 0;
  font-size: 0.9em;
  color: var(--color-muted);
  text-align: center;
}
.photo-caption-below a {
  color: inherit;
}

.photo-exif-overlay {
  position: absolute;
  top: 10px;
  left: 10px;
  max-width: calc(100% - 20px);
  max-height: calc(100% - 20px);
  overflow-y: auto;
  overflow-wrap: anywhere;
  background-color: rgba(0, 0, 0, 0.6);
  color: white;
  padding: 0.5em;
  font-size: 0.8em;
  border-radius: 3px;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.3s ease-in-out,
    visibility 0.3s ease-in-out;
}
@media (hover: hover) {
  .photo-container:hover .photo-exif-overlay,
  .photo-container:focus-within .photo-exif-overlay {
    opacity: 1;
    visibility: visible;
  }
}

/* Tap-to-toggle for touch devices: a hidden checkbox, flipped by the info button, reveals
   the overlays. Visually hidden but kept focusable so the toggle is keyboard-operable. */
.photo-details-toggle,
.photo-details-srlabel {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.photo-details-toggle:checked ~ .photo-exif-overlay,
.photo-details-toggle:checked ~ .photo-caption-overlay {
  opacity: 1;
  visibility: visible;
}

/* The info button is only needed where hover isn't available. */
.photo-details-btn {
  display: none;
}

/* On hover-capable devices the overlays reveal on hover, so the toggle is unused; remove it
   from the layout and a11y tree (otherwise the visually-hidden checkbox stays focusable). */
@media (hover: hover) {
  .photo-details-toggle {
    display: none;
  }
}

.photo-details-toggle:focus-visible ~ .photo-details-btn {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

@media (hover: none) {
  /* On touch the overlays are revealed over the image by the info button (tap-to-toggle).
     They're size-capped (max-width/max-height above) and scroll internally so they can't
     cover the whole photo. Keep the EXIF box clear of the top-right button. */
  .photo-exif-overlay {
    max-width: calc(100% - 60px);
  }

  /* The info button sits in the image's top-right corner, drawn as a white info-circle SVG
     (recoloured via the mask + background-color) with a drop-shadow so it stays legible
     over light photos. */
  .photo-details-btn {
    display: block;
    position: absolute;
    top: 8px;
    right: 8px;
    width: 1.75rem;
    height: 1.75rem;
    cursor: pointer;
    z-index: 2;
    background-color: #fff;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zM8 4a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm1 3H7v6h2z'/%3E%3C/svg%3E")
      center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zM8 4a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm1 3H7v6h2z'/%3E%3C/svg%3E")
      center / contain no-repeat;
  }
  .photo-details-btn::before {
    content: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .photo-caption-overlay,
  .photo-exif-overlay {
    transition: none;
  }
}

/* Styling for items within the EXIF overlay (from exif.html) */
.exif-details .exif-item {
  margin-bottom: 0.3em;
}
.exif-details .exif-item:last-child {
  margin-bottom: 0;
}

/* Year groups on the posts list are <h2> for a correct document outline
   (h1 -> h2), but keep the visual size of the <h3> they used to be. */
.posts-year {
  font-size: 1.17em;
  margin-block: 1em;
}

/* || Tables */

.data-table {
  overflow-x: auto;
  margin-block: 1.5rem;
}

table {
  table-layout: auto;
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95em;
}

caption {
  caption-side: top;
  text-align: start;
  padding-block-end: 0.5rem;
  font-weight: 600;
  color: var(--color-muted);
}

th,
td {
  padding: 0.5rem 0.75rem;
  text-align: start;
}

thead th {
  border-block-end: 2px solid var(--color-border);
}

/* Hairlines between body rows; per-cell alignment from markdown still
   applies via the table shortcode's inline styles. */
tbody th,
tbody td {
  border-block-end: 1px solid color-mix(in srgb, var(--color-muted) 30%, transparent);
}

tfoot th {
  text-align: end;
}


.anchor {
  text-decoration: none;
  margin-left: 0.25em; /* Adjust spacing as needed */
  font-weight: normal;
  opacity: 0.25;

  &:hover,
  &:focus-visible {
    opacity: 0.8;
    text-decoration: underline;
  }
}

/* Keep headings quiet until pointed at; touch devices (no hover) retain
   the always-visible faint anchor above. */
@media (hover: hover) {
  .anchor {
    opacity: 0;
  }

  :is(h1, h2, h3, h4, h5, h6):hover .anchor,
  .anchor:focus-visible {
    opacity: 0.8;
  }
}

#page-title .anchor {
  visibility: hidden;
}

/* || Photo Page (full-screen view, one HTML page per image) */

.photo-page {
  /* Escape the 90ch body cap so the image can use the whole viewport. The
     negative margin trick pulls the panel back to the viewport edges from
     within the constrained <body> + <main>. */
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 1rem clamp(1rem, 3vw, 3rem);
  box-sizing: border-box;
}

.photo-page-nav {
  align-self: flex-start;
  font-size: 0.95em;
}

.photo-page-back {
  text-decoration: none;
}
.photo-page-back:hover,
.photo-page-back:focus-visible {
  text-decoration: underline;
}

.photo-page-figure {
  margin: 0;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.photo-page-figure img {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 8rem);
  height: auto;
  width: auto;
  object-fit: contain;
}

.photo-page-caption {
  max-width: 70ch;
  text-align: center;
  font-size: 0.95em;
  color: var(--color-muted);
}

.photo-page-caption-text {
  margin: 0 0 0.5em;
}

.photo-page-exif {
  font-size: 0.85em;
  opacity: 0.85;
}

/* || Code blocks
   Token colours come from chroma.css (generated, light-dark() aware);
   this is just the shell around them. */

pre {
  overflow-x: auto;
  padding: 0.75rem 1rem;
  border-radius: 4px;
  line-height: 1.5;
  tab-size: 2;
  background-color: var(--color-surface);
}

pre code {
  font-family: var(--font-mono);
  font-size: 0.9em;
}
