/* FONTS
   IBM Plex, served from this site (SIL Open Font License 1.1 — /fonts/OFL.txt)
   rather than from Google Fonts. A visit therefore sends nothing to a third
   party, which is what makes the footer's claim true — and the CSP in
   server.js keeps it true, by refusing fonts from anywhere else.

   Only the faces the stylesheet uses. The two 350 weights (h4, h5) resolve to
   Light; everything else is 400 or 700. */

@font-face {
   font-family: "IBM Plex Mono";
   src: url("/fonts/IBMPlexMono-Regular.ttf") format("truetype");
   font-weight: 400;
   font-style: normal;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Mono";
   src: url("/fonts/IBMPlexMono-Italic.ttf") format("truetype");
   font-weight: 400;
   font-style: italic;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Mono";
   src: url("/fonts/IBMPlexMono-Bold.ttf") format("truetype");
   font-weight: 700;
   font-style: normal;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Sans";
   src: url("/fonts/IBMPlexSans-Light.ttf") format("truetype");
   font-weight: 300;
   font-style: normal;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Sans";
   src: url("/fonts/IBMPlexSans-Regular.ttf") format("truetype");
   font-weight: 400;
   font-style: normal;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Sans";
   src: url("/fonts/IBMPlexSans-Italic.ttf") format("truetype");
   font-weight: 400;
   font-style: italic;
   font-display: swap;
}

@font-face {
   font-family: "IBM Plex Sans";
   src: url("/fonts/IBMPlexSans-Bold.ttf") format("truetype");
   font-weight: 700;
   font-style: normal;
   font-display: swap;
}


:root {
   --bg: #0d1014;
   --text: #e9e9e9;
   --muted: #909090;
   --secondary: #BBB;
   --line: #555;
   --line-faint: #2a2f35;
   --link-external: #93b7d9;

   --sidebar-width: 192px;

   --main-max-width: 640px;

   --header-height: 180px;

   --footer-height: 118px;
   --page-side-padding: 48px;
   --transition: 220ms ease;

   --border: 1px solid var(--line);
}


* {
   box-sizing: border-box;
   margin: 0;
   padding: 0;
}

html {
   scroll-behavior: smooth;
}

body {
   min-height: 100vh;
   background: var(--bg);
   color: var(--text);
   font-family: "IBM Plex Sans", Arial, sans-serif;
   font-size: 15px;
   line-height: 1.5;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4,
h5,
h6 {
   font-family: "IBM Plex Mono", monospace;
   letter-spacing: 0.06em;
}


a {
   color: inherit;
   text-decoration: none;
}

.sans {
   font-family: "IBM Plex Sans", Arial;
}

.site {
   min-height: 100vh;
   display: flex;
   flex-direction: column;
}


/* HEADER */


.page-header {
   width: 100%;
   height: var(--header-height);
   display: grid;
   justify-content: left;
   align-items: center;
}

.page-header-inner {
   margin-left: 64px;
}

.site-brand {
   color: inherit;
   text-decoration: none;
   display: inline-block;
   cursor: pointer;
}

.site-title {
   font-size: 1.5rem;
   font-weight: 400;
   letter-spacing: 0.06em;
   text-transform: uppercase;
   margin-bottom: 4px;
}

.site-tagline {
   font-size: 1.0rem;
   color: var(--secondary);
}



/* SIDEBAR */



.floating-sidebar {
   z-index: 20;
}


.sidebar-inner {
   font-family: "IBM Plex Mono", monospace;
   display: flex;
   flex-direction: column;
   gap: 8px;
}

.sidebar-inner a {
   text-align: right;
   color: var(--secondary);
   display: inline-block;
   transition: color var(--transition), transform var(--transition);
   cursor: pointer;
}

.sidebar-inner a:hover,
.sidebar-inner a:focus-visible,
.sidebar-inner a.active {
   color: var(--text);
   transform: translateX(2px);
   font-weight: 700;
}


/* MAIN  */


.page-main-layout {
   display: grid;
   grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
   column-gap: 64px;
   /* Fill the row rather than size to content. The content column is a
      container (see .page-content), and a container does not lend its text's
      width to the boxes around it — so without this the whole chain sized
      itself to nothing and every page collapsed to a word per line. */
   flex: 1;
   min-width: 0;
}

.floating-sidebar {
   position: sticky;
   top: 48px;
   left: auto;
   width: auto;
   align-self: start;
}

.page-main {
   flex: 1;
   display: flex;
   padding: 0 var(--page-side-padding);
}

.page-main-inner {
   margin-left: 0;
   flex: 1;
   display: flex;
   padding: 0 0 64px 64px;
   border-left: var(--border);
   max-width: var(--main-max-width);
}

.content-rule {
   display: none;
}

.page-content {
   width: 100%;
   /* The program and the tables lay themselves out by the width of this
      column, not the viewport's — the column is narrow on a tablet, on a
      phone, and in a narrow desktop window alike. */
   container-type: inline-size;
}

.page-main p{
   margin-bottom: 1.5em;
}

/* .page-content p+p {
   margin-top: 1.5em;
} */

.page-main h2 {
   font-size: 1.1rem;
   font-weight: 400;
   color: var(--text);
   margin-bottom: 1.0em;
}


.page-main h3{
   font-family: "IBM Plex Sans", sans-serif;
   font-size: 1.2rem;
   font-weight: 400;
   color: var(--text);
   margin-bottom: 1.0em;
}

.page-main h4 {
   font-family: "IBM Plex Sans", sans-serif;
   font-size: 1.1rem;
   font-weight: 350;
   color: var(--text);
   margin-bottom: 0.25em;
}

.page-main h5 {
   font-family: "IBM Plex Sans", sans-serif;
   font-size: 1.0rem;
   font-weight: 350;
   color: var(--text);
   margin-bottom: 1.0em;
}

/* LIST PAGE
   One layout for every entry: the title, then the body. */

.entry-list {
   display: flex;
   flex-direction: column;
   gap: 3rem;
}

.entry-item {
   display: flex;
   flex-direction: column;
   gap: 0.75rem;
   /* Entries are reference targets ([[utomata]] lands on /instruments#utomata);
      keep a landed-on title clear of the sticky navigation on small screens. */
   scroll-margin-top: 4rem;
}

.entry-title {
   margin: 0 !important;
}

.entry-body p {
   font-size: 0.9rem;
   line-height: 1.55;
   max-width: 62ch;
   opacity: 0.92;
   margin-bottom: 1em;
}

.entry-body > :last-child {
   margin-bottom: 0;
}

.entry-empty {
   font-family: "IBM Plex Mono", monospace;
   font-size: 0.85rem;
   color: var(--muted);
}

.list-intro {
   margin-bottom: 3rem;
}

.list-intro > :last-child {
   margin-bottom: 0;
}

.page-content > h2:not(:first-child) {
   margin-top: 3rem;
}


/* TABLES
   The site's one structural element. Every markdown table renders as a ruled
   block whose first column is the label: two columns make a key-value list,
   three make the program. One rule for all of them — ruled above and below,
   nothing between rows. */

.table {
   overflow-x: auto;
   margin-bottom: 1.5em;
}

.entry-body .table {
   margin-bottom: 0.75rem;
}

.table + .table {
   margin-top: 3rem;
}

.page-content table {
   width: 100%;
   border-collapse: collapse;
   border-top: var(--border);
   /* border-bottom: var(--border); */
   font-family: "IBM Plex Mono", monospace;
   font-size: 0.8rem;
   line-height: 1.65;
}

/* A header row is styled exactly as a data row: markdown insists on one, and
   a key-value table has no headers to put in it. Alignment set in markdown
   (|---:|) arrives as an inline style and wins over the left default here. */
.page-content th,
.page-content td {
   padding: 0 0 0 4.5rem;
   text-align: left;
   font-weight: 400;
   vertical-align: baseline;
   opacity: 0.88;
}

/* The label column: as wide as its longest label, and no wider. */
.page-content th:first-child,
.page-content td:first-child {
   width: 1%;
   padding-left: 0;
   white-space: nowrap;
   opacity: 0.5;
   text-transform: lowercase;
}

/* The block's inner margin sits on its first and last rows, whichever section
   they are in — an empty header row is removed, a filled one is data. */
.page-content table > :first-child > tr:first-child > * {
   padding-top: 0.28rem;
}

.page-content table > :last-child > tr:last-child > * {
   padding-bottom: 0.28rem;
}


/* Past the label, columns sit closer: 4.5rem is the distance between a label
   and its value, not between two values of the same row. */
.page-content td + td + td,
.page-content th + th + th {
   padding-left: 1.5rem;
}

@container (min-width: 561px) {
   /* A right-aligned column holds short values — a status — and only reads as
      a column if each stays on one line. In a narrow column there is no room
      for that, and it wraps like everything else. */
   .page-content td[style*="text-align:right"],
   .page-content th[style*="text-align:right"] {
      white-space: nowrap;
   }
}


/* PROGRAM
   The ```program block on the home page: one row per layer of the methodology
   — its name, then its description and the projects in it, each with its own
   status. A rule between layers. Content, not a metadata block. */

.program {
   margin: 0 0 1.5em;
   border-top: var(--border);
   border-bottom: var(--border);
}

.program-row {
   display: grid;
   grid-template-columns: minmax(11ch, max-content) minmax(0, 1fr);
   column-gap: 1.5rem;
   row-gap: 0.4rem;
   padding: 0.9rem 0;
}

.program-row + .program-row {
   border-top: 1px solid var(--line-faint);
}

.program-row .program-name {
   margin: 0;
   font-family: "IBM Plex Mono", monospace;
   font-size: 0.8rem;
   font-weight: 700;
   letter-spacing: normal;
}

.program-row .program-text {
   margin: 0;
   max-width: 62ch;
   font-size: 0.85rem;
   line-height: 1.5;
   opacity: 0.85;
}

.program-row .program-text + .program-text {
   margin-top: 0.6em;
}

.program-projects {
   list-style: none;
   margin-top: 0.6rem;
   font-family: "IBM Plex Mono", monospace;
   font-size: 0.8rem;
   line-height: 1.6;
}

/* Project left, status right: the status column reads down the page. */
.program-projects li {
   display: flex;
   justify-content: space-between;
   align-items: baseline;
   gap: 1.5rem;
}

.program-status {
   text-align: right;
   color: var(--secondary);
   text-transform: lowercase;
   opacity: 0.85;
}


/* NARROW COLUMN
   Below ~560px the label columns take too much of the width: the program's
   layer name moves above its row, and tables close their label gap. */

@container (max-width: 560px) {
   .program-row {
      grid-template-columns: minmax(0, 1fr);
   }

   .page-content th,
   .page-content td {
      padding-left: 1.5rem;
   }
}


/* LINKS IN RUNNING TEXT
   The reset strips underlines, which is right for navigation and wrong for a
   link inside a sentence or a table cell — there it was invisible. */

.page-content p a,
.page-content li a,
.page-content td a,
.page-content th a {
   text-decoration: underline;
   text-decoration-color: var(--line);
   text-underline-offset: 0.2em;
   transition: text-decoration-color var(--transition);
}

.page-content p a:hover,
.page-content li a:hover,
.page-content td a:hover,
.page-content th a:hover {
   text-decoration-color: currentColor;
}

/* Links that leave the site are coloured. An underline alone read as too
   quiet, and colour says where a link goes before it is hovered: white stays
   on this site, blue goes somewhere else. Internal links are always relative,
   so an absolute URL or a mailto is, by construction, external. */
.page-content a[href^="http"],
.page-content a[href^="mailto:"] {
   color: var(--link-external);
   text-decoration-color: color-mix(in srgb, var(--link-external) 40%, transparent);
}

.page-content a[href^="http"]:hover,
.page-content a[href^="mailto:"]:hover {
   text-decoration-color: currentColor;
}



/* FOOTER */

.page-footer {
   width: calc(100% - var(--page-side-padding) * 2);
   border-top: var(--border);
   padding: 64px 0;
   min-height: var(--footer-height);
   margin: 0 auto;
   font-family: "IBM Plex Sans", Arial;
   font-size: 0.8rem;
   color: var(--secondary);
   background: var(--bg);
   z-index: 100;
}

.page-footer-inner {
   display: grid;
   /* Identity, links, details. The outer columns share what is left, so the
      links sit in the middle whatever the other two hold. All three are
      top-aligned: one anchor, not three. */
   grid-template-columns: 1fr auto 1fr;
   gap: 24px;
   align-items: start;
   width: 100%;
}



.footer-left {
   min-width: 0;
}

/* The mark and the wordmark are one object, so they stay on one baseline and
   wrap together rather than the logo orphaning above the name. */
.footer-brand {
   display: flex;
   align-items: center;
   gap: 12px;
}

.footer-mark {
   flex: none;
   display: block;
   width: 32px;
   height: 32px;
}

.footer-left h2 {
   font-size: 1.0rem;
   letter-spacing: 0.06em;
   font-weight: 400;
   margin: 0;
   color: var(--text);
}

.footer-links {
   list-style: none;
   display: flex;
   flex-direction: column;
   gap: 6px;
}

/* External, so blue — the same rule as links in the page. */
.footer-links a {
   color: var(--link-external);
}

.footer-links a:hover,
.footer-links a:focus-visible {
   text-decoration: underline;
   text-underline-offset: 0.2em;
}

.footer-right a:hover,
.footer-right a:focus-visible {
   color: var(--text);
   text-decoration: underline;
}

/* Set in the mono face and spaced like the field labels, so it reads as a
   statement of fact from the site itself rather than a slogan. NOT carries the
   emphasis by brightness alone — italics in an uppercase mono line just look
   like a rendering fault. */
.footer-notice {
   margin-top: 14px;
   font-family: "IBM Plex Mono", monospace;
   font-size: 0.7rem;
   letter-spacing: 0.08em;
   color: var(--muted);
}

.footer-notice strong {
   font-weight: 700;
   color: var(--text);
}

.footer-left strong {
   display: block;

}

.footer-right {
   text-align: right;
}

.footer-right p+p,
.footer-left p+p {
   margin-top: 6px;
}

@media (max-width: 800px) {
   :root {
      --sidebar-width: 128px;
      --page-side-padding: 32px;
   }
}

@media (max-width: 640px) {

   :root {
      --page-side-padding: 32px;
   }

   .page-header {
      height: 128px;
   }

   .page-header-inner {
      margin-left: var(--page-side-padding);
   }

   .page-main-inner {
      margin-left: 0;
      width: 100%;
   }


   .floating-sidebar {
      position: sticky;
      top: 0;
      left: auto;
      width: 100%;
      padding: 0 var(--page-side-padding);
      /* background: linear-gradient(to bottom, rgba(5, 5, 5, 0.98), rgba(5, 5, 5, 0.9), rgba(5, 5, 5, 0)); */
      background: var(--bg);
      z-index: 30;
   }

   .sidebar-inner {
      flex-direction: row;
      flex-wrap: wrap;
      gap: 12px 18px;
      padding: 8px 0 8px;
   }


   .page-main {
      padding: 0 var(--page-side-padding);
   }

   .page-main-layout {
      display: block;
      margin-left: 0;
      margin-right: 0;
   }

   .floating-sidebar {
      position: sticky;
      top: 0;
      width: 100%;
      padding: 0;
      background: var(--bg);
      z-index: 30;
   }

   .sidebar-inner {
      flex-direction: row;
      flex-wrap: wrap;
      gap: 12px 18px;
      padding: 8px 0;
   }

   .page-main-inner {
      max-width: none;
      padding: 32px 0 64px 0;
      border-left: 0;
   }


   .content-rule {
      display: none;
   }


   .page-footer-inner {
      grid-template-columns: 1fr;
   }

   .footer-right {
      text-align: left;
   }
}


/* FULL PAGE TEMPLATE */

.full-page-body {
   padding: 8px;
}

.full-page-site-title {
   font-size: 1.0rem;
   font-weight: 400;
   text-transform: uppercase;
   margin: 0 0 8px 0;
}