/* ==========================================================================
   Latx Technologies — Site chrome and shared components
   --------------------------------------------------------------------------
   Everything that is not a section block: the logo, the sticky site header,
   the primary navigation, the mobile drawer, the footer, and the small shared
   pieces (card, badge, breadcrumb, image frame) that several blocks place.

   BEM: .block, .block__element, .block--modifier. State classes are .is-* and
   .has-*. Full words only — no abbreviated class or token names.

   Requires variables.css, reset.css, global.css.
   ========================================================================== */

/* ============================================================== Logo ====== */

.logo {
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
  font-family: var(--font-family-display);
  font-size: 1.375rem;
  font-weight: var(--font-weight-bold);
  letter-spacing: -0.03em;
  color: var(--color-text-strong);
  text-decoration: none;
}

.logo:hover {
  color: var(--color-text-strong);
}

.logo__mark {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
}

/* A custom logo uploaded in the dashboard replaces the inline mark. Capped by
   height so a wide or a square upload both sit correctly in the header bar. */
.logo__image {
  width: auto;
  max-height: 2.25rem;
}

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

.theme-inverse .logo__accent {
  background: var(--gradient-brand-on-dark);
  background-clip: text;
  -webkit-background-clip: text;
}

/* ============================================================== Card ====== */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-x-small);
  padding: var(--space-medium);
  background-color: var(--color-background-raised);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
  box-shadow: var(--shadow-small);
  transition:
    transform var(--duration-base) var(--easing-out),
    box-shadow var(--duration-base) var(--easing-out),
    border-color var(--duration-base) var(--easing-out);
}

.card--interactive:hover,
.card--interactive:focus-within {
  transform: translateY(-3px);
  border-color: var(--color-border);
  box-shadow: var(--shadow-medium);
}

.card__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-block-end: var(--space-2x-small);
  color: var(--color-accent-text);
  background-color: var(--color-background-accent-soft);
  border-radius: var(--radius-medium);
}

.card__icon svg {
  width: 1.375rem;
  height: 1.375rem;
}

.card__title {
  font-size: var(--font-size-heading-4);
}

.card__text {
  color: var(--color-text-muted);
}

.card__metadata {
  margin-block-start: auto;
  padding-block-start: var(--space-small);
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
}

/* Whole-card link. The pseudo-element covers the card so the click target is
   the whole card, while the accessible name stays the link text itself. */
.card__link {
  font-family: var(--font-family-display);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  text-decoration: none;
}

.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.card__link:hover {
  text-decoration: underline;
}

/* The ring moves from the link to the card, because the link's own box is a
   few words wide while its click target is the whole card. */
.card__link:focus-visible {
  outline: none;
  box-shadow: none;
}

.card:has(.card__link:focus-visible) {
  box-shadow: var(--focus-ring);
}

/* ============================================================= Badge ====== */

.badge {
  display: inline-flex;
  gap: 0.4375rem;
  align-items: center;
  padding: 0.375rem 0.8125rem;
  font-size: 0.78125rem;
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  background-color: var(--color-background-accent-soft);
  border-radius: var(--radius-pill);
}

.badge__dot {
  width: 0.5rem;
  height: 0.5rem;
  background-color: var(--color-success);
  border-radius: 50%;
}

.theme-inverse .badge__dot {
  background-color: var(--color-success-bright);
}

@media (prefers-reduced-motion: no-preference) {
  .badge__dot {
    animation: badge-pulse 2.4s var(--easing-in-out) infinite;
  }
}

@keyframes badge-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }

  50% {
    opacity: 0.55;
    transform: scale(0.82);
  }
}

/* ======================================================== Breadcrumb ====== */

.breadcrumb {
  position: relative;
  z-index: var(--z-index-base);
  margin-block-end: var(--space-medium);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4375rem;
  align-items: center;
}

.breadcrumb__item::after {
  content: "/";
  margin-inline-start: 0.4375rem;
  color: var(--color-text-subtle);
}

.breadcrumb__item:last-child::after {
  content: none;
}

.breadcrumb__link {
  color: var(--color-text-muted);
  text-decoration: none;
}

.breadcrumb__link:hover {
  color: var(--color-text-strong);
  text-decoration: underline;
}

.breadcrumb__current {
  color: var(--color-text-strong);
}

/* ======================================================= Image frame ====== */

/* A standalone photograph in the flow of a page. The frame owns the aspect
   ratio, so the space is reserved before the image decodes and nothing below
   it shifts. reveal.css carries the optional scale-in enhancement. */
.image-frame {
  position: relative;
  overflow: hidden;
  background-color: var(--color-slate-100);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
}

.image-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-frame--wide {
  aspect-ratio: 16 / 9;
}

.image-frame--panorama {
  aspect-ratio: 21 / 9;
}

.image-frame--portrait {
  aspect-ratio: 4 / 5;
}

.image-frame--square {
  aspect-ratio: 1;
}

/* A soft brand wash over photographs used as section backdrops, so text laid
   over them keeps its contrast regardless of the underlying image. */
.image-frame--tinted::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, rgb(10 17 40 / 55%), rgb(47 140 255 / 25%));
  pointer-events: none;
}

/* =========================================================== Figure ====== */

.article-figure {
  margin: 0;
}

.article-figure__image {
  width: 100%;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
}

.article-figure__caption {
  margin-block-start: var(--space-2x-small);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
}

/* ======================================================= Site header ====== */

/* The header carries the inverse theme permanently. It reads as one dark block
   with the hero at the top of the page, and it stays legible over the light
   sections further down without needing JavaScript to swap its colours. */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-index-header);
  background-color: rgb(10 17 40 / 86%);
  border-block-end: 1px solid transparent;
  backdrop-filter: blur(14px);
  transition:
    border-color var(--duration-base) var(--easing-out),
    box-shadow var(--duration-base) var(--easing-out);
}

.site-header--static {
  position: relative;
}

.site-header.is-stuck {
  border-block-end-color: rgb(255 255 255 / 12%);
  box-shadow: 0 6px 24px rgb(8 12 26 / 18%);
}

/* The admin bar is fixed on desktop, so the sticky header has to start below
   it rather than under it. */
.admin-bar .site-header {
  inset-block-start: 32px;
}

@media screen and (width < 783px) {
  .admin-bar .site-header {
    inset-block-start: 46px;
  }
}

.site-header__inner {
  display: flex;
  gap: var(--space-medium);
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-height);
}

.site-header__actions {
  display: flex;
  gap: var(--space-2x-small);
  align-items: center;
}

.site-header__call-to-action {
  display: none;
}

@media (width >= 64rem) {
  .site-header__call-to-action {
    display: inline-flex;
  }
}

/* =============================================== Primary navigation ====== */

.primary-navigation {
  display: none;
}

@media (width >= 64rem) {
  .primary-navigation {
    display: block;
  }
}

.primary-navigation__list {
  display: flex;
  gap: var(--space-3x-small);
  align-items: center;
}

.primary-navigation__item {
  position: relative;
}

.primary-navigation__link {
  display: inline-flex;
  gap: 0.375rem;
  align-items: center;
  padding: 0.5rem 0.75rem;
  font-family: var(--font-family-display);
  font-size: 0.9375rem;
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  text-decoration: none;
  border-radius: var(--radius-small);
  transition:
    color var(--duration-fast) var(--easing-out),
    background-color var(--duration-fast) var(--easing-out);
}

.primary-navigation__link:hover,
.primary-navigation__item:hover > .primary-navigation__link,
.primary-navigation__item:focus-within > .primary-navigation__link {
  color: var(--color-text-strong);
  background-color: var(--color-background-raised);
}

.primary-navigation__link[aria-current="page"],
.primary-navigation__link--active {
  color: var(--color-accent-text);
}

/* --- Submenu -------------------------------------------------------------- */

/* A WordPress menu with children renders a second level. It opens on hover and
   on focus, so it is reachable with a keyboard without any script. */
.primary-navigation__submenu {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  z-index: var(--z-index-drawer);
  display: grid;
  gap: 0.125rem;
  min-width: 14rem;
  padding: var(--space-2x-small);
  background-color: var(--color-surface-dark-raised);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: var(--radius-medium);
  box-shadow: var(--shadow-large);
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.375rem);
  transition:
    opacity var(--duration-fast) var(--easing-out),
    transform var(--duration-fast) var(--easing-out),
    visibility var(--duration-fast);
}

.primary-navigation__item:hover > .primary-navigation__submenu,
.primary-navigation__item:focus-within > .primary-navigation__submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.primary-navigation__submenu .primary-navigation__link {
  display: flex;
  padding: 0.5rem 0.625rem;
}

/* ======================================================= Menu toggle ====== */

.menu-toggle {
  display: grid;
  place-items: center;
  width: var(--minimum-target-size);
  height: var(--minimum-target-size);
  color: var(--color-text-strong);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-medium);
}

@media (width >= 64rem) {
  .menu-toggle {
    display: none;
  }
}

.menu-toggle__bars {
  display: grid;
  gap: 5px;
  width: 1.125rem;
}

.menu-toggle__bars i {
  display: block;
  height: 2px;
  background-color: currentcolor;
  border-radius: 1px;
  transition: transform var(--duration-base) var(--easing-out);
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bars i:first-child {
  transform: translateY(3.5px) rotate(45deg);
}

.menu-toggle[aria-expanded="true"] .menu-toggle__bars i:last-child {
  transform: translateY(-3.5px) rotate(-45deg);
}

/* ===================================================== Mobile drawer ====== */

.mobile-drawer {
  position: fixed;
  inset: var(--header-height) 0 0;
  z-index: var(--z-index-drawer);
  overflow-y: auto;
  padding: var(--space-medium) var(--container-gutter) var(--space-2x-large);
  background-color: var(--color-background);
  border-block-start: 1px solid var(--color-border-subtle);
}

.admin-bar .mobile-drawer {
  inset-block-start: calc(var(--header-height) + 46px);
}

@media screen and (width >= 783px) {
  .admin-bar .mobile-drawer {
    inset-block-start: calc(var(--header-height) + 32px);
  }
}

.mobile-drawer[hidden] {
  display: none;
}

@media (width >= 64rem) {
  .mobile-drawer {
    display: none;
  }
}

.mobile-drawer__group + .mobile-drawer__group {
  margin-block-start: var(--space-medium);
  padding-block-start: var(--space-medium);
  border-block-start: 1px solid var(--color-border-subtle);
}

.mobile-drawer__heading {
  margin-block-end: var(--space-2x-small);
  font-size: var(--font-size-overline);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-overline);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

.mobile-drawer__link {
  display: block;
  min-height: var(--minimum-target-size);
  padding: 0.6875rem 0;
  font-family: var(--font-family-display);
  font-size: 1.0625rem;
  font-weight: var(--font-weight-medium);
  color: var(--color-text-strong);
  text-decoration: none;
}

.mobile-drawer__link:hover {
  color: var(--color-accent-text);
}

/* Second-level items sit indented under their parent rather than behind a
   second tap, which keeps the whole menu one scroll. */
.mobile-drawer__submenu {
  padding-inline-start: var(--space-small);
  border-inline-start: 2px solid var(--color-border-subtle);
}

.mobile-drawer__submenu .mobile-drawer__link {
  font-size: 1rem;
  font-weight: var(--font-weight-regular);
  color: var(--color-text-muted);
}

.mobile-drawer__call-to-action {
  margin-block-start: var(--space-large);
}

/* ======================================================= Site footer ====== */

.site-footer {
  padding-block: var(--space-2x-large) var(--space-large);
}

.site-footer__top {
  display: grid;
  gap: var(--space-x-large);
}

@media (width >= 48rem) {
  .site-footer__top {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  }
}

.site-footer__blurb {
  max-width: 34ch;
  margin-block-start: var(--space-small);
  color: var(--color-text-muted);
}

/* Two explicit columns rather than auto-fit, which produced a lopsided row at
   some widths. */
.site-footer__navigation {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-large) var(--space-medium);
}

/* Three columns once there is room for them. Below this the third column
   simply wraps under the other two rather than squeezing all three. */
@media (width >= 40rem) {
  .site-footer__navigation {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Grid items default to min-width:auto, so a long unbreakable string — the
   email address in the address block — would widen its column and push the
   whole page past the viewport. */
.site-footer__navigation > * {
  min-width: 0;
}

.site-footer__heading {
  margin-block-end: var(--space-x-small);
  font-family: var(--font-family-body);
  font-size: var(--font-size-overline);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-overline);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

.site-footer__link {
  display: inline-block;
  padding-block: 0.3125rem;
  font-size: 0.9375rem;
  color: var(--color-text-muted);
  text-decoration: none;
}

.site-footer__link:hover {
  color: var(--color-text-strong);
  text-decoration: underline;
}

.site-footer__details {
  margin-block-start: var(--space-small);
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-small);
  font-style: normal;
  line-height: 1.9;
  color: var(--color-text-subtle);
  overflow-wrap: break-word;
}

/* The email address is one long unbreakable token inside a shrink-to-fit
   inline-block, so it needs `anywhere` — which, unlike `break-word`, also
   lowers the element's min-content width. Without it the address sets a floor
   on the footer column and pushes the whole page wider than a phone viewport.
   At desktop widths the column is wide enough that no break occurs. */
.site-footer__details a {
  overflow-wrap: anywhere;
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-small) var(--space-medium);
  align-items: center;
  justify-content: space-between;
  margin-block-start: var(--space-x-large);
  padding-block-start: var(--space-medium);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
  border-block-start: 1px solid var(--color-border-subtle);
}

/* ====================================================== Social links ====== */

.social-links {
  display: flex;
  gap: var(--space-2x-small);
  margin-block-start: var(--space-medium);
}

.social-links__link {
  display: grid;
  place-items: center;
  width: var(--minimum-target-size);
  height: var(--minimum-target-size);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-small);
  transition:
    color var(--duration-fast) var(--easing-out),
    border-color var(--duration-fast) var(--easing-out);
}

.social-links__link:hover {
  color: var(--color-text-strong);
  border-color: var(--color-border-strong);
}

.social-links__link svg {
  width: 1.0625rem;
  height: 1.0625rem;
}

/* ==================================================== Pagination ====== */

/* The numbered pager under the blog archive and the search results. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3x-small);
  align-items: center;
  justify-content: center;
  margin-block-start: var(--space-2x-large);
}

.pagination .page-numbers {
  display: grid;
  place-items: center;
  min-width: var(--minimum-target-size);
  min-height: var(--minimum-target-size);
  padding-inline: var(--space-2x-small);
  font-family: var(--font-family-display);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-decoration: none;
  background-color: var(--color-background-raised);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-small);
  transition:
    color var(--duration-fast) var(--easing-out),
    border-color var(--duration-fast) var(--easing-out);
}

.pagination .page-numbers:hover {
  color: var(--color-text-strong);
  border-color: var(--color-border-strong);
}

.pagination .page-numbers.current {
  color: var(--color-white);
  background-image: var(--gradient-brand);
  border-color: transparent;
}

.pagination .page-numbers.dots {
  background: none;
  border-color: transparent;
}

/* ================================================== Search form ====== */

.search-form {
  display: flex;
  gap: var(--space-2x-small);
  max-width: 28rem;
}

.search-form__input {
  flex: 1;
  min-height: var(--minimum-target-size);
  padding: 0.6875rem 0.875rem;
  color: var(--color-text);
  background-color: var(--color-background-raised);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-small);
}

.search-form__input:focus-visible {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px rgb(46 107 246 / 14%);
}

/* ==================================================== Related links ====== */

/* The onward-link card. Declared globally rather than in the Related Links
   block, because single.php, search.php and 404.php all place one and none of
   them loads a block stylesheet. */

.related-links {
  display: grid;
  gap: var(--space-small);
}

@media (width >= 48rem) {
  .related-links {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.related-link {
  position: relative;
  display: grid;
  gap: var(--space-3x-small);
  padding: var(--space-medium);
  background-color: var(--color-background-raised);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
  transition:
    transform var(--duration-base) var(--easing-out),
    box-shadow var(--duration-base) var(--easing-out);
}

.related-link:hover,
.related-link:focus-within {
  transform: translateY(-3px);
  box-shadow: var(--shadow-medium);
}

.related-link__title {
  font-size: var(--font-size-heading-4);
}

.related-link__title a {
  color: inherit;
  text-decoration: none;
}

/* Whole-card click target, while the accessible name stays the link text. */
.related-link__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.related-link__text {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}

/* ========================================================= Data table ===== */

/* Declared globally rather than in the Table block, because single-project.php
   renders a project facts table and root templates never load a block
   stylesheet. Missing these left the case study table with a centred caption,
   no padding and no column widths. */

/* The one element allowed to be wider than the page. Its own scroll container
   takes the overflow so the document body never scrolls sideways. */
.table-scroll {
  overflow-x: auto;
}

.definition-table {
  width: 100%;
  border-collapse: collapse;
  text-align: start;
}

.definition-table caption {
  margin-block-end: var(--space-small);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
  text-align: start;
}

.definition-table th,
.definition-table td {
  padding: var(--space-x-small) var(--space-small);
  vertical-align: top;
  border-block-end: 1px solid var(--color-border-subtle);
  text-align: start;
}

/* A row header, in the label-and-value shape: one per row, in the leading
   column. Padding comes off the leading edge so it lines up with the copy
   beside the table rather than sitting indented. Scoped to tbody so a plain
   column heading in a wider table is never forced to this width. */
.definition-table tbody th {
  width: 34%;
  padding-inline-start: 0;
  font-family: var(--font-family-display);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-strong);
}

.definition-table td {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* The trailing column closes on the table's own edge, whichever shape the
   table is: the value column of a row-header table, or the last of several
   plain columns. */
.definition-table tr > :last-child {
  padding-inline-end: 0;
}

.definition-table thead th {
  font-size: var(--font-size-small);
  letter-spacing: var(--letter-spacing-overline);
  text-transform: uppercase;
  color: var(--color-text-subtle);
  border-block-end-color: var(--color-border);
}

/* The last row closes on the table's own edge, so a stack of rows does not end
   on a rule that looks like a dropped border. */
.definition-table tbody tr:last-child th,
.definition-table tbody tr:last-child td {
  border-block-end: 0;
}

/* ======================================================== Page header ===== */

/* The dark banner at the top of an inner page. Declared globally because six
   root templates render one (single, single-project, archive-project, index,
   search and 404) and none of them loads a block stylesheet. The Page Header
   block reuses this and adds only its own background variants. */

.page-header {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem) clamp(2.5rem, 1.5rem + 4vw, 4rem);
  background-image: var(--gradient-ink);
}

.page-header__glow {
  position: absolute;
  inset-block-start: -40%;
  inset-inline-end: -8%;
  width: min(30rem, 55vw);
  height: min(30rem, 55vw);
  background: radial-gradient(circle, var(--color-brand-blue), transparent 68%);
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.42;
  pointer-events: none;
}

.page-header__inner {
  position: relative;
  z-index: var(--z-index-base);
  display: grid;
  gap: var(--space-medium);
  justify-items: start;
  max-width: 46rem;
}

.page-header__title {
  font-size: var(--font-size-heading-1);
  letter-spacing: var(--letter-spacing-tight);
}

.page-header__lead {
  max-width: 52ch;
  font-size: var(--font-size-body-large);
  color: var(--color-text-muted);
}

/* ========================================================== Work card ===== */

/* The project card. Global because archive-project.php lists them, and both
   single-project.php and the Work block render a related strip of them. */

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

@media (width >= 48rem) {
  .work-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

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

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

.work-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: var(--color-background-raised);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
  transition:
    transform var(--duration-base) var(--easing-out),
    box-shadow var(--duration-base) var(--easing-out);
}

.work-card:hover,
.work-card:focus-within {
  transform: translateY(-3px);
  box-shadow: var(--shadow-medium);
}

.work-card__thumbnail {
  aspect-ratio: 16 / 10;
  width: 100%;
  object-fit: cover;
  background-color: var(--color-slate-100);
  border-block-end: 1px solid var(--color-border-subtle);
}

.work-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-3x-small);
  padding: var(--space-medium);
}

.work-card__label {
  margin-block-end: var(--space-3x-small);
}

.work-card__sector {
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
}

.work-card__title {
  font-size: var(--font-size-heading-4);
}

.work-card__title a {
  color: inherit;
  text-decoration: none;
}

/* Whole-card click target, while the accessible name stays the title text. */
.work-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.work-card__summary {
  color: var(--color-text-muted);
}

.work-card__result {
  margin-block-start: auto;
  padding-block-start: var(--space-small);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success);
  border-block-start: 1px solid var(--color-border-subtle);
}

/* ========================================================== Post card ===== */

/* Global because index.php is the blog archive and renders these directly. */

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

@media (width >= 48rem) {
  .post-grid,
  .post-grid--two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width >= 64rem) {
  .post-grid--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.post-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2x-small);
  overflow: hidden;
  padding: var(--space-medium);
  background-color: var(--color-background-raised);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-large);
  transition:
    transform var(--duration-base) var(--easing-out),
    box-shadow var(--duration-base) var(--easing-out);
}

.post-card:hover,
.post-card:focus-within {
  transform: translateY(-3px);
  box-shadow: var(--shadow-medium);
}

/* The featured card leads the grid: wider, with room for a longer summary. */
.post-card--featured {
  gap: var(--space-x-small);
  padding: var(--space-large) var(--space-medium);
  background-image: var(--gradient-soft);
}

@media (width >= 48rem) {
  .post-card--featured {
    grid-column: 1 / -1;
  }
}

/* The ratio reserves the space before the image decodes, which keeps
   Cumulative Layout Shift at zero. */
.post-card__thumbnail {
  aspect-ratio: 16 / 9;
  width: 100%;
  margin-block-end: var(--space-2x-small);
  object-fit: cover;
  background-color: var(--color-slate-100);
  border-radius: var(--radius-medium);
}

.post-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2x-small) var(--space-x-small);
  align-items: center;
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-small);
  color: var(--color-text-subtle);
}

.post-card__topic {
  color: var(--color-accent-text);
}

.post-card__title {
  font-size: var(--font-size-heading-3);
}

.post-card--featured .post-card__title {
  font-size: var(--font-size-heading-2);
}

.post-card__title a {
  color: inherit;
  text-decoration: none;
}

.post-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.post-card__summary {
  max-width: 60ch;
  color: var(--color-text-muted);
}

.post-card__footer {
  margin-block-start: auto;
  padding-block-start: var(--space-x-small);
  font-family: var(--font-family-display);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
}

/* ============================================================= Filter ===== */

/* Shared by the Work block, the Blog Listing block and the work archive.
   Buttons rather than links, because this filters a list already on the page
   and navigates nowhere. The row is hidden in the markup and revealed by
   theme.js, so it never appears without behaviour behind it. */

.post-filter {
  display: grid;
  gap: var(--space-x-small);
  margin-block-end: var(--space-large);
}

.post-filter__label {
  font-family: var(--font-family-body);
  font-size: var(--font-size-overline);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-overline);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

.post-filter__options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3x-small);
}

.post-filter__option {
  min-height: var(--minimum-target-size);
  padding: 0.5rem 1rem;
  font-family: var(--font-family-display);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  background-color: var(--color-background-raised);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition:
    color var(--duration-fast) var(--easing-out),
    background-color var(--duration-fast) var(--easing-out),
    border-color var(--duration-fast) var(--easing-out);
}

.post-filter__option:hover {
  color: var(--color-text-strong);
  border-color: var(--color-border-strong);
}

/* The selected state is carried by aria-pressed as well as this class, so it
   is announced rather than only shown. */
.post-filter__option.is-selected {
  color: var(--color-background-raised);
  background-color: var(--color-text-strong);
  border-color: var(--color-text-strong);
}

.post-grid__empty {
  margin-block-start: var(--space-medium);
  color: var(--color-text-muted);
}

.post-grid__reset {
  padding: 0;
  font: inherit;
  color: var(--color-accent-text);
  text-decoration: underline;
  background: none;
  border: 0;
  cursor: pointer;
}
