/* Open Sans, served from this site (SIL Open Font License, see assets/fonts/OFL.txt). */
@font-face { font-family: "Open Sans"; font-weight: 400; font-display: swap; src: url(/assets/fonts/open-sans-latin-400-normal.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Open Sans"; font-weight: 600; font-display: swap; src: url(/assets/fonts/open-sans-latin-600-normal.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+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Open Sans"; font-weight: 400; font-display: swap; src: url(/assets/fonts/open-sans-latin-ext-400-normal.woff2) format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: "Open Sans"; font-weight: 600; font-display: swap; src: url(/assets/fonts/open-sans-latin-ext-600-normal.woff2) format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
/* Stand-in while Open Sans loads: Arial resized to take the same room, so lines don't re-break. */
@font-face { font-family: "Open Sans Fallback"; font-weight: 400; src: local("Arial"), local("ArialMT"), local("Liberation Sans");
  size-adjust: 106.02%; ascent-override: 100.81%; descent-override: 27.63%; line-gap-override: 0%; }
@font-face { font-family: "Open Sans Fallback"; font-weight: 600; src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold");
  size-adjust: 101.69%; ascent-override: 105.11%; descent-override: 28.81%; line-gap-override: 0%; }

/* sotirov.com: one stylesheet. Colours and spacing come from the old portfolio. */

:root {
  --text: #464b63;        /* home page text */
  --article-text: #000;   /* article pages */
  --muted: #aab;          /* old: note, subtitle */
  --header-shadow: 0 1px 6px rgb(0 0 0 / .08);
  --hint: #889;           /* old: "Click/tap images to enlarge" */
  --lead: #545462;        /* blurb at the top of an article */
  --page-bg: #f9f9fb;     /* old: article pages (home stays white) */
  --ext-icon: #000;       /* old: black at 50% opacity */
  --link: #1558b7;
  --link-hover: #193f85;
  --bg: #fff;
  --rule: #e6e7ee;
  /* Column widths, as in the old portfolio:
     page area = window minus 25px each side (max 1170px);
     text column = 680px, or 90% of the page area under 870px, 96% under 570px;
     wide images = 90% of the page area (max ~1053px), 96% under 570px. */
  --page: min(1170px, 100vw - 50px);
  --col: min(680px, var(--page));
  --wide: calc(var(--page) * .9);
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --text: #d6d8e2;
    --article-text: #d6d8e2;
    --muted: #8d91a5;
    --header-shadow: 0 1px 8px rgb(0 0 0 / .45);
    --hint: #8d91a5;
    --lead: #aeb1c2;
    --page-bg: #1b1c22;
    --ext-icon: #d6d8e2;
    --link: #7aa7f0;
    --link-hover: #a9c6f6;
    --bg: #15161b;
    --rule: #2a2c35;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font: 400 1rem/2 "Open Sans", "Open Sans Fallback", system-ui, sans-serif;
}
main, .related { flex: 1 0 auto; }
body.article { background: var(--page-bg); color: var(--article-text); }
.prose { padding-top: 6px; }   /* old: content began 6px below the 124px header */
/* An article that opens with text or a note (not a section title) starts 12px lower. */
.prose > :first-child:not(h2) { margin-top: 12px; }
@media (max-width: 870px) { :root { --col: calc(var(--page) * .9); } }
@media (max-width: 570px) { :root { --col: calc(var(--page) * .96); --wide: var(--col); } }

body > * { width: var(--col); margin-inline: auto; }

a { color: var(--link); text-decoration: underline 1px transparent; text-underline-offset: .25em; transition: color .2s, text-decoration-color .2s; }
a:hover { color: var(--link-hover); text-decoration-color: currentColor; }   /* thin underline appears on hover */
a:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; border-radius: 2px; }
b, strong { font-weight: 600; }

/* Header */
/* Header sizes follow the old portfolio: a 44px top bar (16px + 28px logo line), then the
   title block (16px + 32px title line + 32px subtitle line) = 124px in all. */
.masthead { --bar: 44px; background: var(--bg); }
/* The header's background spans the whole window; its content keeps the column width. */
body > .masthead { width: 100%; }
.masthead > * { width: var(--col); margin-inline: auto; }
/* Logo and tagline sit at the far left/right of the wide page area, 15px in (old .logo). */
.masthead > .site-header { width: var(--page); padding-inline: 15px; }
@media (max-width: 400px) { .masthead > .site-header { padding-inline: 0; } }   /* keeps the tagline on one line on the narrowest phones */
.site-header {
  min-height: var(--bar);
  padding-top: 16px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 0 1rem;
  font-size: .9rem;
  font-weight: 600;
  letter-spacing: 3px;
  text-transform: uppercase;
}
.site-header > * { line-height: 28px; }
.site-header .brand { color: var(--text); }
.site-header a.brand { color: var(--link); }
.site-header .tagline { letter-spacing: .08em; text-transform: none; font-weight: 400; font-size: 1rem; }

/* Laptops/desktops: the bar slides away on scroll down and returns on scroll up;
   on article pages the title stays pinned (as in the old portfolio). Phones: static. */
@media (min-width: 870px) and (hover: hover) {
  /* Fixed like the old portfolio; header.js reserves its height at the top of the page. */
  .masthead { position: fixed; top: 0; left: 0; right: 0; z-index: 10; transition: transform .3s ease, box-shadow .3s ease; }
  /* Light shadow while the header lies over the page (anywhere but the very top). */
  .masthead.scrolled { box-shadow: var(--header-shadow); }
  /* Pinned (as old): moves up 60px, title shrinks to 1.5rem on a 24px line → a 59px strip. */
  .masthead.hide { transform: translateY(-60px); }
  .masthead .article-head { transition: padding .3s ease; }
  .masthead h1, .masthead .subtitle { transition: font-size .8s, line-height .8s; }   /* old: .8s */
  .masthead.hide .article-head { padding-top: 19px; }
  .masthead.hide h1 { font-size: 1.5rem; line-height: 24px; }
  .masthead.hide .subtitle { font-size: .85rem; }
}

/* Home */
.intro { text-align: center; margin: 2rem 0 2.5rem; font-size: 1.1rem; }
.home-image { margin: 0 0 2.5rem; }
.home-image img { display: block; width: auto; height: auto; max-width: var(--wide); max-height: 20vh; margin: 0 0 0 50%; transform: translateX(-50%); border-radius: 50%; }   /* round, a fifth of the window height; no zoom, no label */
.article-list { list-style: none; padding: 0; margin: 0 0 3rem; text-align: center; }
.article-list li { margin-bottom: 2.5rem; line-height: 1.5; }
.article-list > li > a { font-size: 1.2rem; font-weight: 600; }   /* the titles only; links inside a blurb stay at blurb size */
.article-list p { margin: .25rem 4rem 0; font-size: .9rem; line-height: 1.8; }
@media (max-width: 570px) { .article-list p { margin-inline: 1rem; } }

.list-label { margin: 0 0 .5rem; color: var(--muted); font-size: 1rem; }
.featured { padding-bottom: 1.25rem; margin-bottom: 2.75rem; border-bottom: 1px solid var(--rule); }
.featured .article-list { margin-bottom: 0; }

/* Article */
.article-head { text-align: center; padding-block: 16px 0; }
.article-head h1 { margin: 0 0 5px 0; font-size: 1.7rem; font-weight: 400; letter-spacing: .5px; line-height: 32px; }
.subtitle { margin: 0 0 6px 0; color: var(--muted); font-size: .9rem; line-height: 1.1rem; }

/* Section titles: normal case (long titles read badly in capitals), 1.3rem, 1rem above, 1.4rem below (as much as between paragraphs) */
.prose h2 {
  margin: 0;
  padding: 1rem 0 1.4rem;
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.5;
}
.prose p { margin: 0 0 1.2rem; }
/* A centred block: add {.center} on the line after the paragraph */
.prose .center { text-align: center; }
/* Separator (--- in Markdown): three spaced dots, centred, with section-title spacing around it */
.prose hr { border: 0; margin: 35px 0; height: 32px; line-height: 32px; text-align: center; color: var(--muted); overflow: visible; }
.prose hr::before { content: "· · ·"; letter-spacing: .4em; margin-right: -.4em; font-size: 1.6rem; font-weight: 600; color: var(--hint); }
/* Lists (old): 50px indent, pulled 10px closer to the text above, 16px between items */
.prose ul, .prose ol { margin: -.6rem 0 1.2rem; padding-left: 50px; }
.prose li { margin-bottom: 1rem; padding-left: .15rem; line-height: 1.8; }
.prose li:first-child { margin-top: .6rem; }
/* Lists exported with blank lines between items: keep normal list spacing */
.prose li > p { margin: 0; }

/* Quote: a long quotation, indented (add {.quote} on the line after the paragraph) */
.prose .quote { margin-left: 2rem; }
@media (max-width: 570px) { .prose .quote { margin-left: 1rem; } }

/* Tables: text-column width, slightly smaller text, thin lines between rows. Columns share
   the width by percentage (first column narrower); on phones the table keeps a readable
   width and scrolls sideways inside its box. */
.prose .table-wrap { margin: 0 0 1.6rem; overflow-x: auto; }
.prose .table-note { display: none; }   /* phones only: "(The table has N columns)" (see the phone rules below) */
.prose table { width: 100%; min-width: 34rem; border-collapse: collapse; table-layout: fixed; font-size: .9rem; line-height: 1.6; }
.prose th, .prose td { padding: .6rem .8rem .6rem 0; text-align: left; vertical-align: top; border-bottom: 1px solid var(--rule); }
.prose th { font-weight: 600; border-bottom-color: var(--muted); }
.prose th:first-child, .prose td:first-child { width: 28%; }
.prose th:not(:first-child), .prose td:not(:first-child) { width: 36%; }
/* References: a numbered list set slightly smaller (add {.references} on the line after the list) */
.prose .references { font-size: .9rem; }
.prose .references li { line-height: 1.7; margin-bottom: .6rem; }

/* Section heading aside: ## Team *(of co-founders)* */
.prose h2 em { font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; }

/* Note: a "> " paragraph, centred, italic, muted */
.prose blockquote { margin: 0; padding: 0; text-align: center; font-style: italic; color: var(--muted); }
.prose blockquote p { margin: 0; }

.prose .hint { margin: 0; font-style: italic; color: var(--hint); }
/* The blurb, shown at the top of each article: centred, italic, grey (like a note), then a paragraph gap */
.prose .lead { margin: 0 4rem 1.2rem; text-align: center; color: var(--lead); font-size: .9rem; line-height: 1.8; }
@media (max-width: 570px) { .prose .lead { margin-inline: 1rem; } }

/* Links to other sites: small "opens elsewhere" mark */
.prose a[target="_blank"]::after {
  content: "";
  display: inline-block;
  width: 1em;
  height: 1em;
  margin: 0 0 .15em .1em;
  vertical-align: text-bottom;
  background: var(--ext-icon);
  opacity: .5;
  -webkit-mask: var(--ext) center / contain no-repeat;
          mask: var(--ext) center / contain no-repeat;
}
:root { --ext: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ij48cGF0aCBkPSJNOSAyTDkgMyAxMi4zIDMgNiA5LjMgNi43IDEwIDEzIDMuNyAxMyA3IDE0IDcgMTQgMlpNNCA0QzIuOSA0IDIgNC45IDIgNkwyIDEyQzIgMTMuMSAyLjkgMTQgNCAxNEwxMCAxNEMxMS4xIDE0IDEyIDEzLjEgMTIgMTJMMTIgNyAxMSA4IDExIDEyQzExIDEyLjYgMTAuNiAxMyAxMCAxM0w0IDEzQzMuNCAxMyAzIDEyLjYgMyAxMkwzIDZDMyA1LjQgMy40IDUgNCA1TDggNSA5IDRaIi8+PC9zdmc+); }

/* Images and videos. Default: wider than the text column on big screens (screenshots
   need the room), with the old soft shadow. {.medium}: text-column width, no shadow, no zoom. */
.prose img, .prose video {
  display: block;
  width: auto;
  height: auto;
  max-width: var(--wide);
  max-height: 80vh;   /* tall (portrait) images fit the window; the width follows the proportions */
  margin: 0 0 0 50%;
  transform: translateX(-50%);
  box-shadow: 0 0 20px rgb(101 119 134 / .2), 0 0 3px 1px rgb(101 119 134 / .08);
}
.prose video { width: auto; background: #000; }   /* never wider than the video itself */
.prose img.medium, .prose video.medium { max-width: 100%; margin-inline: auto; transform: none; box-shadow: none; }
.prose img.zoomable { cursor: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xNS44NTMgMTYuNTZjLTEuNjgzIDEuNTE3LTMuOTExIDIuNDQtNi4zNTMgMi40NC01LjI0MyAwLTkuNS00LjI1Ny05LjUtOS41czQuMjU3LTkuNSA5LjUtOS41IDkuNSA0LjI1NyA5LjUgOS41YzAgMi40NDItLjkyMyA0LjY3LTIuNDQgNi4zNTNsNy40NCA3LjQ0LS43MDcuNzA3LTcuNDQtNy40NHptLTYuMzUzLTE1LjU2YzQuNjkxIDAgOC41IDMuODA5IDguNSA4LjVzLTMuODA5IDguNS04LjUgOC41LTguNS0zLjgwOS04LjUtOC41IDMuODA5LTguNSA4LjUtOC41em0tNC41IDhoNHYtNGgxdjRoNHYxaC00djRoLTF2LTRoLTR2LTF6Ii8+PC9zdmc+) 10 10, zoom-in; }
/* Spacing around images (old): 20px above (+ the text's 19px), 51px below;
   a paragraph after a wide image or video gets 32px more (old "first-p"). */
.prose { --img-above: 20px; --img-below: 51px; }
@media (max-width: 870px) { .prose { --img-above: 15px; --img-below: 56px; } }
@media (max-width: 570px) { .prose { --img-above: 10px; --img-below: 41px; } }
.prose p.media { margin: 0 0 var(--img-below); padding-top: var(--img-above); }
.prose p.media.wide + p:not(.media):not(.credit), .prose p.media.wide + p.credit + p { padding-top: 2rem; }   /* old "first-p" after a wide image or video */

/* Attribution label under an image: the cover's cover_credit, or a "… {.credit}" line right after an image */
.prose .credit { margin: 8px 0 0; font-size: .8rem; line-height: 1.5; text-align: center; color: var(--hint); }
.prose p.media:has(+ .credit) { margin-bottom: 0; }
.prose p.media + p.credit { margin-bottom: var(--img-below); }

/* Cover: the image at the top of an article (cover: in the settings); no shadow, enlarges on click */
.prose .cover { margin: 0 0 2rem; }
.prose .cover p.media { margin: 0; padding: 0; }
.prose .cover img { box-shadow: none; max-height: 50vh; }   /* covers stay modest: half the window height at most */

/* Loading without jumps: each image's size is known at build time (--w, --h), so it takes
   its final box at once, using the same limits as above (--maxw, --maxh), never upscaled.
   Until it arrives, a tiny blurred preview (--ph) fills the box; then it comes into focus. */
.prose img, .home-image img { --maxw: var(--wide); --maxh: 80vh; }
.prose img.medium { --maxw: 100%; }
.prose .cover img { --maxh: 50vh; }
.home-image img { --maxh: 20vh; }
.prose img[style], .home-image img[style] {
  width: min(calc(var(--w) * 1px), var(--maxw), calc(var(--maxh) * var(--w) / var(--h)));
  aspect-ratio: var(--w) / var(--h);
  transition: filter .6s ease;
}
html.js .prose img[style]:not(.loaded), html.js .home-image img[style]:not(.loaded) {
  background: var(--ph) center / cover no-repeat;
  filter: blur(12px);
  clip-path: inset(0);   /* keeps the blur inside the image's box */
}
html.js .home-image img[style]:not(.loaded) { clip-path: inset(0 round 50%); }
img.instant { transition: none; }

.related { padding-block: 1rem 2rem; }
.related h2 { text-align: center; font-size: 1rem; font-weight: 600; margin: 2rem 0 1.25rem; }

/* Footer */
.site-footer {
  display: flex;
  justify-content: space-between;
  padding-block: 1.5rem;
  border-top: 1px solid var(--rule);
  font-size: .9rem;
  color: var(--muted);
}
/* Article pages: extra space above the footer line (visible gap ≈ 7 + 19 + 52 = ~78px). */
body.article .site-footer { margin-top: 52px; }

/* Image zoom */
dialog.zoom { max-width: 100vw; max-height: 100vh; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; background: transparent; cursor: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xNS44NTMgMTYuNTZjLTEuNjgzIDEuNTE3LTMuOTExIDIuNDQtNi4zNTMgMi40NC01LjI0MyAwLTkuNS00LjI1Ny05LjUtOS41czQuMjU3LTkuNSA5LjUtOS41IDkuNSA0LjI1NyA5LjUgOS41YzAgMi40NDItLjkyMyA0LjY3LTIuNDQgNi4zNTNsNy40NCA3LjQ0LS43MDcuNzA3LTcuNDQtNy40NHptLTYuMzUzLTE1LjU2YzQuNjkxIDAgOC41IDMuODA5IDguNSA4LjVzLTMuODA5IDguNS04LjUgOC41LTguNS0zLjgwOS04LjUtOC41IDMuODA5LTguNSA4LjUtOC41em0tNC41IDhoOXYxaC05di0xeiIvPjwvc3ZnPg==) 10 10, zoom-out; }
dialog.zoom[open] { display: flex; align-items: center; justify-content: center; }
dialog.zoom::backdrop { background: rgb(0 0 0 / .8); }
/* Fits the screen, but never shown larger than its real size */
dialog.zoom img { max-width: 100%; max-height: 100%; width: auto; height: auto; animation: zoom-in .6s; }
@keyframes zoom-in { from { transform: scale(.95); } to { transform: scale(1); } }   /* old: .95 → 1 over .6s */

/* Phones: larger base text (18px instead of 16px; every rem size scales with it),
   slightly tighter line spacing, as in the old portfolio */
@media (max-width: 870px) { .prose ul, .prose ol { padding-left: 30px; } }
@media (max-width: 570px) {
  html { font-size: 18px; }
  .prose .table-note { display: block; margin: 0 0 .6rem; }
  .prose p, .prose li { line-height: 1.7; }
  .prose h2 { font-size: 1.15rem; }
  /* keep logo + tagline on one line in the narrow phone column */
  .site-header { column-gap: .5rem; }
  .site-header .tagline { font-size: .9rem; letter-spacing: .02em; }
}
