/* Required Notice: Copyright 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
   SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 */

/* petrbalvin.org · design system 2026
   Modern, calm, fast: the colours live in styles/palettes/, one palette on per
   page, and every accent in this sheet derives from the palette tokens. Glass
   header, cards that lift, the dark scheme an equal citizen, not an inversion.
   Served as written, nothing compiled. */

@property --bg {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(98.2% 0.008 280);
}

@layer reset, tokens, base, layout, components, utilities;

@layer tokens {
  :root {
    /* The scheme follows the system until the visitor pins one with the toggle: the
       light-dark() tokens read the resolved colour scheme, and a data-theme attribute
       exists only to pin it. */
    color-scheme: light dark;

    --font-ui: "Ubuntu", ui-sans-serif, system-ui, "DejaVu Sans", sans-serif;
    --font-mono:
      "Ubuntu Mono",
      ui-monospace,
      "Cascadia Mono",
      "DejaVu Sans Mono",
      monospace;

    /* The palette colours are not here: every page links exactly one file from
       styles/palettes/ after this sheet, and that file carries --bg, --surface,
       --ink, --line, --accent, --accent-2 and --on-accent. What stays here is
       what derives from them, and what no palette owns. */
    --accent-wash: light-dark(
      color-mix(in oklab, var(--accent) 8%, transparent),
      color-mix(in oklab, var(--accent) 16%, transparent)
    );
    --gradient: linear-gradient(
      100deg,
      var(--accent) 8%,
      color-mix(in oklab, var(--accent) 45%, var(--accent-2)) 55%,
      var(--accent-2) 100%
    );
    --glow: light-dark(
      color-mix(in oklab, var(--accent) 26%, transparent),
      color-mix(in oklab, var(--accent) 40%, transparent)
    );
    --danger: light-dark(oklch(50% 0.19 26), oklch(74% 0.14 26));
    --ok: light-dark(oklch(48% 0.13 155), oklch(78% 0.13 155));

    --text-xs: 0.8125rem;
    --text-sm: 0.9062rem;
    --text-base: 1.0312rem;
    --text-lg: clamp(1.12rem, 0.3vw + 1.05rem, 1.25rem);
    --text-xl: clamp(1.25rem, 0.6vw + 1.1rem, 1.5rem);
    --text-2xl: clamp(1.5rem, 1.3vw + 1.16rem, 2rem);
    --text-display: clamp(2.5rem, 5vw + 0.8rem, 4.35rem);

    --space-3xs: 0.25rem;
    --space-2xs: 0.4rem;
    --space-xs: 0.6rem;
    --space-sm: 0.9rem;
    --space-md: 1.25rem;
    --space-lg: 1.8rem;
    --space-xl: 2.8rem;
    --space-2xl: 5rem;
    --space-3xl: 7.5rem;

    --radius-sm: 10px;
    --radius: 16px;
    --radius-lg: 22px;
    --content: 74rem;
    --measure: 66ch;
    --gutter: clamp(1.25rem, 4vw, 2.75rem);
    --header-h: 4.25rem;

    --shadow-sm: 0 1px 2px light-dark(
      oklch(20% 0.02 268 / 0.05),
      oklch(0% 0 0 / 0.3)
    );
    --shadow-md:
      0 1px 2px light-dark(oklch(20% 0.02 268 / 0.05), oklch(0% 0 0 / 0.32)),
      0 10px 30px -12px light-dark(oklch(20% 0.02 268 / 0.14), oklch(0% 0 0 / 0.5));
    --shadow-lg:
      0 2px 4px light-dark(oklch(20% 0.02 268 / 0.05), oklch(0% 0 0 / 0.34)),
      0 22px 50px -16px light-dark(oklch(20% 0.02 268 / 0.2), oklch(0% 0 0 / 0.6));
  }

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

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

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  * {
    margin: 0;
  }

  html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* The page scrollbar wears the site: thin, the palette's accent on an
       invisible track, both schemes through light-dark(), and a reserved
       gutter so short pages do not shift the centred layout. */
    scrollbar-width: thin;
    scrollbar-color: var(--accent) transparent;
    scrollbar-gutter: stable;
  }

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

  input,
  button,
  textarea,
  select {
    font: inherit;
    color: inherit;
  }

  ul[class],
  ol[class],
  nav ul,
  .menu ul,
  .site-footer ul {
    list-style: none;
    padding: 0;
  }

  [hidden] {
    display: none !important;
  }
}

@layer base {
  body {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    background-color: var(--bg);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    transition:
      background-color 0.3s ease,
      color 0.3s ease;
  }

  /* The dot grid: a printed lattice over the top of the page that thins out on the
     way down. No colour fields, just clearly visible dots: mid grey in the light
     scheme, lifted grey in the dark one. */
  body::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: min(46rem, 90svh);
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(
      light-dark(color-mix(in oklab, var(--ink-3) 62%, transparent), color-mix(in oklab, var(--ink-2) 42%, transparent)) 1.3px,
      transparent 1.5px
    );
    background-size: 26px 26px;
    mask-image: linear-gradient(to bottom, black 60%, transparent);
  }

  main {
    flex: 1;
  }

  h1,
  h2,
  h3,
  h4 {
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -0.022em;
    text-wrap: balance;
  }

  h1 {
    font-size: var(--text-display);
    letter-spacing: -0.035em;
  }

  h2 {
    font-size: var(--text-2xl);
    letter-spacing: -0.028em;
  }

  h3 {
    font-size: var(--text-xl);
  }

  h4 {
    font-size: var(--text-lg);
  }

  p {
    text-wrap: pretty;
  }

  a {
    color: var(--accent);
    text-decoration: underline;
    text-decoration-color: color-mix(in oklab, var(--accent) 38%, transparent);
    text-decoration-thickness: 1.5px;
    text-underline-offset: 0.2em;
    transition:
      color 0.18s ease,
      text-decoration-color 0.18s ease;
  }

  @media (hover: hover) {
    a:hover {
      text-decoration-color: currentColor;
    }
  }

  strong,
  b {
    font-weight: 650;
  }

  code,
  kbd,
  samp {
    font-family: var(--font-mono);
    font-size: 0.875em;
  }

  :not(pre) > code {
    padding: 0.12em 0.4em;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface-2);
  }

  ::selection {
    background: color-mix(in oklab, var(--accent) 26%, transparent);
  }

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

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.25s;
  }
}

@layer layout {
  .wrap {
    width: min(100% - (2 * var(--gutter)), var(--content));
    margin-inline: auto;
  }

  .section {
    padding-block: var(--space-2xl);
  }

  .section--tight {
    padding-block: var(--space-xl);
  }

  /* Anchored sections land whole under the sticky header, not behind it. */
  .section[id] {
    scroll-margin-top: calc(var(--header-h) + 1rem);
  }

  .section__head {
    display: grid;
    gap: var(--space-sm);
    max-width: 46rem;
    margin-bottom: var(--space-xl);
  }

  .section__note {
    font-size: var(--text-lg);
    color: var(--ink-2);
  }

  .lede {
    font-size: var(--text-lg);
    line-height: 1.55;
    color: var(--ink-2);
  }

  .prose {
    max-width: var(--measure);
  }

  .prose > * + * {
    margin-top: var(--space-md);
  }

  .grid {
    display: grid;
    gap: var(--space-md);
  }

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

    .grid--3 {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
  }

  @media (min-width: 56rem) {
    .grid--4 {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    /* The minor-language cards ride in this grid, so they stay small beside the
       featured primary language. */
    .grid--4 .card {
      padding: var(--space-md);
    }
  }

  .split {
    display: grid;
    gap: var(--space-xl);
    align-items: start;
  }

  @media (min-width: 56rem) {
    .split {
      grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    }
  }

  .page-head {
    display: grid;
    gap: var(--space-md);
    max-width: 52rem;
    padding-block: var(--space-2xl) var(--space-lg);
  }

  .page-head__title {
    font-size: clamp(2.1rem, 4vw + 0.6rem, 3.4rem);
  }

  .page-head__lede {
    font-size: var(--text-lg);
    color: var(--ink-2);
    max-width: 46rem;
  }
}

@layer components {
  .skip-link {
    position: absolute;
    z-index: 30;
    top: 0.6rem;
    left: 0.6rem;
    padding: 0.6rem 1rem;
    translate: 0 -5rem;
    border-radius: 999px;
    background: var(--surface);
    box-shadow: var(--shadow-lg);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    transition: translate 0.2s ease;
  }

  .skip-link:focus-visible {
    translate: 0;
  }

  .site-header {
    position: sticky;
    z-index: 20;
    top: 0;
    border-bottom: 1px solid color-mix(in oklab, var(--line) 72%, transparent);
    background: color-mix(in oklab, var(--bg) 74%, transparent);
    -webkit-backdrop-filter: blur(16px) saturate(1.5);
    backdrop-filter: blur(16px) saturate(1.5);
  }

  .site-header__inner {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    min-height: var(--header-h);
  }

  .brand {
    display: grid;
    gap: 0.05rem;
    margin-right: auto;
    text-decoration: none;
    color: var(--ink);
  }

  .brand__name {
    font-size: var(--text-lg);
    font-weight: 750;
    letter-spacing: -0.025em;
    line-height: 1.15;
  }

  .brand__role {
    display: none;
    font-size: var(--text-xs);
    color: var(--ink-3);
  }

  @media (min-width: 62rem) {
    .brand__role {
      display: block;
    }
  }

  .site-nav {
    display: none;
  }

  @media (min-width: 56rem) {
    .site-nav {
      display: block;
    }
  }

  .site-nav ul {
    display: flex;
    align-items: center;
    gap: 0.2rem;
  }

  .site-nav a {
    display: block;
    padding: 0.45rem 0.85rem;
    border-radius: 999px;
    font-size: var(--text-sm);
    font-weight: 520;
    color: var(--ink-2);
    text-decoration: none;
    transition:
      color 0.18s ease,
      background-color 0.18s ease;
  }

  @media (hover: hover) {
    .site-nav a:hover {
      color: var(--ink);
      background: var(--accent-wash);
    }
  }

  .site-nav a[aria-current="page"] {
    color: var(--accent);
    background: var(--accent-wash);
    font-weight: 620;
  }

  .site-tools {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
  }

  .lang {
    display: flex;
    align-items: center;
    padding: 2px;
    border-radius: 999px;
    background: var(--surface-2);
    font-size: var(--text-xs);
    font-weight: 620;
  }

  .lang__current,
  .lang__link {
    padding: 0.28rem 0.62rem;
    border-radius: 999px;
    text-decoration: none;
  }

  .lang__current {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-sm);
  }

  .lang__link {
    color: var(--ink-3);
    transition: color 0.18s ease;
  }

  @media (hover: hover) {
    .lang__link:hover {
      color: var(--accent);
    }
  }

  .icon-btn {
    display: grid;
    place-items: center;
    width: 2.3rem;
    height: 2.3rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--ink-2);
    cursor: pointer;
    transition:
      color 0.18s ease,
      background-color 0.18s ease,
      rotate 0.3s ease;
  }

  @media (hover: hover) {
    .icon-btn:hover {
      color: var(--accent);
      background: var(--accent-wash);
    }
  }

  .icon-btn svg {
    width: 1.15rem;
    height: 1.15rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .menu-toggle {
    display: grid;
  }

  @media (min-width: 56rem) {
    .menu-toggle {
      display: none;
    }
  }

  /* One icon per mode: the monitor stands for following the system, and the sun
     and moon for the two pins. Exactly one shows at a time. */
  .theme-toggle .icon--system,
  .theme-toggle .icon--sun,
  .theme-toggle .icon--moon {
    display: none;
  }

  :root:not([data-theme]) .theme-toggle .icon--system {
    display: block;
  }

  :root[data-theme="light"] .theme-toggle .icon--sun {
    display: block;
  }

  :root[data-theme="dark"] .theme-toggle .icon--moon {
    display: block;
  }

  .menu {
    position: fixed;
    inset: auto 0.6rem auto 0.6rem;
    top: calc(var(--header-h) + 0.5rem);
    width: auto;
    margin: 0;
    padding: var(--space-xs);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    translate: 0 -0.5rem;
    transition:
      opacity 0.18s ease,
      translate 0.18s ease,
      display 0.18s allow-discrete,
      overlay 0.18s allow-discrete;
  }

  .menu:popover-open {
    opacity: 1;
    translate: 0;
  }

  @starting-style {
    .menu:popover-open {
      opacity: 0;
      translate: 0 -0.5rem;
    }
  }

  .menu::backdrop {
    background: color-mix(in oklab, oklch(18% 0.02 268) 40%, transparent);
  }

  .menu ul {
    display: grid;
  }

  .menu a {
    display: block;
    padding: 0.8rem 0.9rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    font-weight: 550;
    color: var(--ink);
    text-decoration: none;
  }

  @media (hover: hover) {
    .menu a:hover {
      background: var(--accent-wash);
    }
  }

  .menu a[aria-current="page"] {
    color: var(--accent);
    background: var(--accent-wash);
  }

  /* The hero: the one place the site speaks in the first person plural of type sizes. */
  .hero {
    display: grid;
    gap: var(--space-lg);
    padding-block: var(--space-2xl) var(--space-xl);
    max-width: 56rem;
  }

  .eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    width: fit-content;
    padding: 0.35rem 0.9rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--ink-2);
  }

  .eyebrow::before {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 999px;
    background: var(--accent);
  }

  .grad {
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  .hero__lede {
    font-size: var(--text-lg);
    line-height: 1.6;
    color: var(--ink-2);
    max-width: 44rem;
  }

  .hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
  }

  .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.72rem 1.35rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--ink);
    font-size: var(--text-sm);
    font-weight: 620;
    text-decoration: none;
    cursor: pointer;
    transition:
      translate 0.18s ease,
      box-shadow 0.18s ease,
      background-color 0.18s ease,
      border-color 0.18s ease,
      color 0.18s ease,
      filter 0.18s ease;
  }

  .btn svg {
    width: 1rem;
    height: 1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  @media (hover: hover) {
    .btn:hover {
      translate: 0 -1px;
    }
  }

  .btn--primary {
    background: var(--gradient);
    color: var(--on-accent);
    border-color: transparent;
    box-shadow: 0 8px 26px -8px var(--glow);
  }

  @media (hover: hover) {
    .btn--primary:hover {
      filter: brightness(1.08);
      box-shadow: 0 12px 32px -8px var(--glow);
    }
  }

  .btn--ghost {
    border-color: var(--line-strong);
    background: var(--surface);
  }

  @media (hover: hover) {
    .btn--ghost:hover {
      border-color: var(--accent);
      color: var(--accent);
    }
  }

  .btn[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
    translate: none;
  }

  .card {
    position: relative;
    display: grid;
    gap: var(--space-xs);
    align-content: start;
    padding: var(--space-lg);
    border: 1px solid color-mix(in oklab, var(--line) 88%, transparent);
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--surface) 88%, transparent);
    box-shadow: var(--shadow-sm);
    transition:
      translate 0.22s ease,
      box-shadow 0.22s ease,
      border-color 0.22s ease;
  }

  @media (hover: hover) {
    .card:hover {
      translate: 0 -3px;
      border-color: color-mix(in oklab, var(--accent) 30%, var(--line));
      box-shadow: var(--shadow-md);
    }

    /* A featured card keeps its gradient hairline under the pointer: the border
       stays transparent, or the hover colour would cover the gradient painted
       behind it in the border box. */
    .card--feature:hover {
      border-color: transparent;
    }
  }

  .card__icon {
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 12px;
    background: var(--accent-wash);
    color: var(--accent);
    margin-bottom: var(--space-2xs);
  }

  .card__icon svg {
    width: 1.35rem;
    height: 1.35rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* The research line heads: a section head that wears the card icon a size up,
     beside the title and its note, so each line opens with its own mark. */
  .section__head--line {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: var(--space-sm) var(--space-md);
  }

  .section__head--line .card__icon {
    width: 3rem;
    height: 3rem;
    margin-bottom: 0;
    border-radius: 14px;
  }

  .section__head--line .card__icon svg {
    width: 1.5rem;
    height: 1.5rem;
  }

  .section__head__text {
    display: grid;
    gap: var(--space-2xs);
  }

  .card h2,
  .card h3,
  .card h4 {
    font-size: var(--text-lg);
    letter-spacing: -0.015em;
  }

  .card__text {
    font-size: var(--text-sm);
    line-height: 1.6;
    color: var(--ink-2);
  }

  .card__link {
    margin-top: var(--space-2xs);
    font-size: var(--text-sm);
    font-weight: 620;
    text-decoration: none;
  }

  .card__link::after {
    content: "→";
    margin-left: 0.3rem;
    transition: margin 0.18s ease;
  }

  .card:hover .card__link::after {
    margin-left: 0.5rem;
  }

  /* The featured card carries the gradient as a hairline border. */
  .card--feature {
    border: 1px solid transparent;
    background:
      linear-gradient(var(--surface), var(--surface)) padding-box,
      var(--gradient) border-box;
    box-shadow: var(--shadow-md);
  }

  .cta {
    display: grid;
    gap: var(--space-md);
    justify-items: center;
    padding: var(--space-2xl) var(--space-lg);
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    background:
      linear-gradient(color-mix(in oklab, var(--surface) 92%, transparent), var(--surface)) padding-box,
      var(--gradient) border-box;
    box-shadow: var(--shadow-lg);
    text-align: center;
  }

  .cta h2 {
    font-size: var(--text-2xl);
    max-width: 24ch;
  }

  .cta p {
    max-width: 46ch;
    color: var(--ink-2);
  }

  .facts {
    display: grid;
    gap: var(--space-xs);
  }

  .facts > div {
    display: grid;
    gap: var(--space-3xs);
    padding: var(--space-md);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--surface) 88%, transparent);
  }

  @media (min-width: 40rem) {
    .facts > div {
      grid-template-columns: 12rem 1fr;
      gap: var(--space-md);
      align-items: baseline;
    }
  }

  .facts dt {
    font-size: var(--text-sm);
    font-weight: 620;
    color: var(--ink-3);
  }

  .facts dd {
    font-size: var(--text-sm);
    color: var(--ink);
  }

  .group-title {
    margin-block: var(--space-sm) var(--space-md);
    font-size: var(--text-lg);
    font-weight: 700;
    letter-spacing: -0.015em;
    color: var(--ink-2);
  }

  .note {
    max-width: var(--measure);
    padding: var(--space-md) var(--space-lg);
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    background: var(--accent-wash);
    color: var(--ink);
    font-size: var(--text-sm);
  }

  .form {
    display: grid;
    gap: var(--space-md);
  }

  .field {
    display: grid;
    gap: var(--space-2xs);
  }

  .field__label {
    font-size: var(--text-sm);
    font-weight: 620;
  }

  .field__hint {
    font-size: var(--text-xs);
    color: var(--ink-3);
  }

  .control {
    width: 100%;
    padding: 0.68rem 0.9rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: var(--text-base);
    transition:
      border-color 0.18s ease,
      box-shadow 0.18s ease;
  }

  .control:hover {
    border-color: var(--ink-3);
  }

  .control:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-wash);
  }

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

  .control[aria-invalid="true"] {
    border-color: var(--danger);
  }

  .field:has([aria-invalid="true"]) .field__label {
    color: var(--danger);
  }

  .field__error {
    font-size: var(--text-xs);
    font-weight: 550;
    color: var(--danger);
  }

  .check {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-xs);
    align-items: start;
  }

  .check input {
    width: 1.1rem;
    height: 1.1rem;
    margin-top: 0.22rem;
    accent-color: var(--accent);
  }

  .check label {
    font-size: var(--text-sm);
    color: var(--ink-2);
  }

  .form__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-md);
  }

  .status {
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--line);
    border-left: 3px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: var(--text-sm);
  }

  .status--ok {
    border-color: var(--ok);
    border-left-color: var(--ok);
    background: color-mix(in oklab, var(--ok) 8%, var(--surface));
  }

  .status--error {
    border-color: var(--danger);
    border-left-color: var(--danger);
    background: color-mix(in oklab, var(--danger) 8%, var(--surface));
  }

  /* The no-JavaScript receipt: nuntius redirects a plain form post to
     /cs/contact/#form-sent (or /en/…) and the target shows itself. */
  .form-sent {
    display: none;
    margin-bottom: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--ok);
    border-left: 3px solid var(--ok);
    border-radius: var(--radius-sm);
    background: color-mix(in oklab, var(--ok) 8%, var(--surface));
    font-size: var(--text-sm);
  }

  .form-sent:target {
    display: block;
  }

  .honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  .site-footer {
    margin-top: var(--space-2xl);
    padding-block: var(--space-xl) var(--space-xl);
    border-top: 1px solid var(--line);
    background: color-mix(in oklab, var(--surface) 55%, transparent);
    font-size: var(--text-sm);
    color: var(--ink-2);
  }

  .site-footer__grid {
    display: grid;
    gap: var(--space-lg);
  }

  @media (min-width: 48rem) {
    .site-footer__grid {
      grid-template-columns: 1.5fr 1fr 1fr;
      gap: var(--space-xl);
    }
  }

  .site-footer h2 {
    margin-bottom: var(--space-xs);
    font-size: var(--text-xs);
    font-weight: 680;
    letter-spacing: 0.04em;
    color: var(--ink-3);
  }

  .site-footer ul {
    display: grid;
    gap: var(--space-2xs);
  }

  .site-footer a {
    color: var(--ink-2);
    text-decoration-color: color-mix(in oklab, var(--accent) 30%, transparent);
  }

  @media (hover: hover) {
    .site-footer a:hover {
      color: var(--accent);
    }
  }

  .colophon {
    max-width: 34ch;
    color: var(--ink-3);
  }

  .colophon a {
    font-weight: 650;
  }

  .site-footer__base {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-md);
    justify-content: space-between;
    margin-top: var(--space-xl);
    padding-top: var(--space-md);
    border-top: 1px solid var(--line);
    font-size: var(--text-xs);
    color: var(--ink-3);
  }

  /* The palette switch beside the copyright line: two names, the one on screen
     carrying the accent, so the control shows the palette it would leave. */
  .palette {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.15rem;
    border: 1px solid var(--line);
    border-radius: 999px;
  }

  .palette__option {
    padding: 0.1rem 0.7rem;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--ink-3);
    font: inherit;
    font-size: var(--text-xs);
    cursor: pointer;
  }

  @media (hover: hover) {
    .palette__option:hover {
      color: var(--ink);
    }
  }

  .palette__option[aria-pressed="true"] {
    background: var(--accent-wash);
    color: var(--accent);
    font-weight: 620;
  }
}

/* The numbers band: four verifiable figures under the hero. The value is set in the
     mono face and painted with the gradient, so the row reads as a receipt. */
.stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  box-shadow: var(--shadow-sm);
}

@media (min-width: 48rem) {
  .stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.stats > div {
  display: grid;
  gap: var(--space-3xs);
  padding: var(--space-md) var(--space-md);
  background: color-mix(in oklab, var(--surface) 92%, transparent);
}

.stats dd {
  font-family: var(--font-mono);
  font-size: clamp(1.7rem, 2.6vw + 0.9rem, 2.5rem);
  font-weight: 700;
  line-height: 1.1;
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.stats dt {
  order: 2;
  font-size: var(--text-xs);
  font-weight: 560;
  color: var(--ink-3);
}

/* The engagement timeline: a printed line down the left of the steps, with the dot
     marking each one. Steps never carry numbers. */
.timeline {
  position: relative;
  display: grid;
  gap: var(--space-lg);
  padding-left: 1.6rem;
}

.timeline::before {
  content: "";
  position: absolute;
  top: 0.55rem;
  bottom: 0.55rem;
  left: 0.3rem;
  width: 2px;
  background: linear-gradient(to bottom, var(--accent), var(--accent-2));
  opacity: 0.55;
}

.timeline > li {
  position: relative;
  display: grid;
  gap: var(--space-2xs);
}

.timeline > li::before {
  content: "";
  position: absolute;
  top: 0.32rem;
  left: -1.6rem;
  width: 0.7rem;
  height: 0.7rem;
  border: 2px solid var(--bg);
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 40%, transparent);
}

.timeline h3 {
  font-size: var(--text-lg);
}

.timeline p {
  font-size: var(--text-sm);
  color: var(--ink-2);
  max-width: 58ch;
}

/* The project record: a full-width row with the name taking its own column, the
     body beside it, and the verification callout closing it. */
.record {
  display: grid;
  gap: var(--space-md);
  padding: var(--space-xl) var(--space-lg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  box-shadow: var(--shadow-sm);
  scroll-margin-top: calc(var(--header-h) + 1rem);
  transition:
    border-color 0.22s ease,
    box-shadow 0.22s ease;
}

@media (hover: hover) {
  .record:hover {
    border-color: color-mix(in oklab, var(--accent) 30%, var(--line));
    box-shadow: var(--shadow-md);
  }
}

/* The records are one list, so the cards carry the gap between them; the section
   head already holds its own distance above the first one. */
.record + .record {
  margin-top: var(--space-lg);
}

@media (min-width: 56rem) {
  .record {
    grid-template-columns: 16rem minmax(0, 1fr);
    gap: var(--space-xl);
    align-items: start;
  }
}

.record__head {
  display: grid;
  gap: var(--space-xs);
  align-content: start;
}

.record__head h2 {
  font-size: var(--text-xl);
  letter-spacing: -0.02em;
}

.record__body {
  display: grid;
  gap: var(--space-sm);
}

.record__body p {
  color: var(--ink-2);
  max-width: 62ch;
}

.callout {
  display: flex;
  gap: var(--space-xs);
  align-items: baseline;
  padding: var(--space-sm) var(--space-md);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--accent-wash);
  font-size: var(--text-sm);
}

.callout::before {
  content: "→";
  flex: none;
  font-weight: 700;
  color: var(--accent);
}

/* The article card, used in the list and in the home teaser. */
.post {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-lg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: var(--ink);
  transition:
    translate 0.22s ease,
    border-color 0.22s ease,
    box-shadow 0.22s ease;
}

@media (hover: hover) {
  .post:hover {
    translate: 0 -3px;
    border-color: color-mix(in oklab, var(--accent) 30%, var(--line));
    box-shadow: var(--shadow-md);
  }

  .post:hover h3 {
    color: var(--accent);
  }
}

.post__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-3);
}

.post h3 {
  font-size: var(--text-lg);
  transition: color 0.18s ease;
}

.post p {
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.post--feature {
  grid-column: 1 / -1;
  border: 1px solid transparent;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    var(--gradient) border-box;
}

/* Article states on the posts page, and the article body itself. */
.posts-state {
  display: grid;
  place-items: center;
  gap: var(--space-xs);
  padding: var(--space-2xl) var(--space-md);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-2);
  text-align: center;
}

/* The article view: one reading column, centred in the wrap, with the full
   typographic set the Markdown renderer emits. */
.article {
  max-width: 46rem;
  margin-inline: auto;
  padding-block: var(--space-lg) var(--space-3xl);
}

.article__head {
  display: grid;
  gap: var(--space-sm);
  margin-bottom: var(--space-xl);
  padding-bottom: var(--space-lg);
  border-bottom: 1px solid var(--line);
}

.article__head h1 {
  font-size: clamp(1.9rem, 3.4vw + 0.6rem, 2.9rem);
  text-wrap: balance;
}

.article__head .post__meta {
  margin: 0;
  color: var(--ink-3);
}

.article__head .cite-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: 0;
}

.article__head .cite {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-2);
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color 0.15s ease;
}

@media (hover: hover) {
  .article__head .cite:hover {
    color: var(--accent);
  }
}

.article__body {
  font-size: var(--text-base);
  line-height: 1.75;
}

.article__body > * + * {
  margin-top: var(--space-md);
}

.article__body h2 {
  margin-top: var(--space-xl);
  font-size: var(--text-2xl);
}

.article__body h3 {
  margin-top: var(--space-lg);
  font-size: var(--text-xl);
}

.article__body a {
  color: var(--accent);
  text-underline-offset: 0.15em;
}

.article__body ul,
.article__body ol {
  padding-left: 1.4rem;
}

.article__body li + li {
  margin-top: var(--space-2xs);
}

/* A quote in the article reads like the callout component: one accent edge on
   a wash of the accent colour. */
.article__body blockquote {
  padding: var(--space-sm) var(--space-md);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--accent-wash);
  color: var(--ink-2);
}

.article__body blockquote > * + * {
  margin-top: var(--space-sm);
}

.article__body code {
  padding: 0.1em 0.4em;
  border-radius: 6px;
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 0.92em;
}

.article__body pre {
  overflow-x: auto;
  padding: var(--space-md);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: var(--text-sm);
  line-height: 1.6;
}

.article__body pre code {
  padding: 0;
  background: none;
  font-size: inherit;
}

.article__body table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--line);
}

.article__body th,
.article__body td {
  padding: var(--space-2xs) var(--space-sm);
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
  text-align: left;
}

.article__body th {
  background: var(--surface-2);
  font-weight: 620;
}

.article__body tr:last-child td {
  border-bottom: 0;
}

.article__body img {
  max-width: 100%;
  border-radius: var(--radius-sm);
}

.article__body hr {
  margin-top: var(--space-xl);
  border: 0;
  border-top: 1px solid var(--line);
}

/* The bibliography the engine splices at the [[refs]] marker: a compact
     numbered list with hanging entries, and the inline [n] citations that
     point into it. */
.article__body .refs {
  margin-top: var(--space-lg);
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.article__body .refs ol {
  padding-left: 1.8rem;
  display: grid;
  gap: var(--space-2xs);
}

.article__body a.ref-cite {
  font-family: var(--font-mono);
  font-size: 0.82em;
  text-decoration: none;
  vertical-align: 0.2em;
  color: var(--accent);
}

@media (hover: hover) {
  .article__body a.ref-cite:hover {
    text-decoration: underline;
  }
}

.article__body .refs .refs-link {
  font-family: var(--font-mono);
  font-size: 0.86em;
  white-space: nowrap;
}

/* Back to top: a floating affordance that appears once the page has been read
     far enough to need it. */
.backtotop {
  position: fixed;
  right: 1.1rem;
  bottom: 1.1rem;
  z-index: 15;
  display: grid;
  place-items: center;
  width: 2.7rem;
  height: 2.7rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 86%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-md);
  color: var(--ink-2);
  cursor: pointer;
  opacity: 0;
  translate: 0 0.6rem;
  pointer-events: none;
  transition:
    opacity 0.22s ease,
    translate 0.22s ease,
    color 0.18s ease,
    border-color 0.18s ease;
}

.backtotop.is-visible {
  opacity: 1;
  translate: 0;
  pointer-events: auto;
}

@media (hover: hover) {
  .backtotop:hover {
    color: var(--accent);
    border-color: var(--accent);
  }
}

.backtotop svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Reveal on scroll: the element slides the last stretch into place. The state is
     one class written by the observer; without JavaScript everything is visible. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    translate: 0 1.1rem;
    transition:
      opacity 0.55s ease,
      translate 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  .js .reveal.is-in {
    opacity: 1;
    translate: 0 0;
  }
}

/* The 404 page speaks in the mono face, because it is a stack trace in disguise. */
.notfound {
  display: grid;
  gap: var(--space-md);
  justify-items: center;
  padding-block: var(--space-3xl);
  text-align: center;
}

.notfound__code {
  font-family: var(--font-mono);
  font-size: clamp(4.5rem, 12vw + 1rem, 9rem);
  font-weight: 700;
  line-height: 1;
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@layer utilities {
  .measure {
    max-width: var(--measure);
  }

  /* A vertical stack: the blocks in the contact aside, and any other column that
     carries more than one block. */
  .stack > * + * {
    margin-top: var(--space-lg);
  }

  .mt-md {
    margin-top: var(--space-md);
  }

  .mt-lg {
    margin-top: var(--space-lg);
  }

  .mt-xl {
    margin-top: var(--space-xl);
  }
}

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

@media print {
  body::before,
  .site-header,
  .site-footer__grid,
  .form,
  .skip-link,
  .theme-toggle,
  .menu-toggle,
  .lang,
  .btn {
    display: none;
  }

  body {
    background: #fff;
    color: #000;
  }

  .grad {
    color: #000;
    background: none;
  }

  .card,
  .cta {
    border-color: #bbb;
    box-shadow: none;
    background: #fff;
  }
}
