/* ============================================================
   MODULES — per-section component styles
   Each block maps to a data-module in the HTML.
   Fill in as design direction arrives.
   ============================================================ */

/* ----------------------------------------------------------
   FADE — scroll-triggered fade-in utility
   Add data-fade to a wrapper div. Add data-fade-delay="ms" to
   any descendant element to stagger them individually.
   If no descendants carry data-fade-delay, the container fades.
   JS (initFade) adds .is-visible when the element enters view.
---------------------------------------------------------- */
[data-fade] {
  opacity: 0;
  transform: translateY(5vh);
  transition:
    opacity 2000ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 1400ms cubic-bezier(0.16, 1, 0.3, 1);
}

[data-fade].is-visible {
  opacity: 1;
  transform: translateY(0);
}

[data-fade] [data-fade-delay] {
  opacity: 0;
  transform: translateY(5vh);
  transition:
    opacity 2000ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 1400ms cubic-bezier(0.16, 1, 0.3, 1);
}

[data-fade] [data-fade-delay].is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  [data-fade],
  [data-fade] [data-fade-delay] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ----------------------------------------------------------
   IMG-FADE — scroll-triggered fade-in for <Img> images
   JS (initImgReveal) adds .is-visible once the image is both
   in view and decoded. Pure opacity, no movement, so large
   media reveals elegantly without any apparent layout shift.
---------------------------------------------------------- */
.img-fade {
  opacity: 0;
  transition: opacity 1100ms cubic-bezier(0.16, 1, 0.3, 1);
}

.img-fade.is-visible {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .img-fade {
    opacity: 1;
    transition: none;
  }
}

/* ----------------------------------------------------------
   MENU OVERLAY
   Full-screen 3×2 grid. Nav (z-index: 100) sits above it.
   Toggle .is-open to open / close.
---------------------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  z-index: 90; /* below nav (100) so nav bar stays visible */
  background: #000;
  display: flex;
  flex-direction: column;

  /* Closed state */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 280ms var(--ease-out),
    visibility 0s 280ms;
}

.menu.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: all;
  transition:
    opacity 280ms var(--ease-out),
    visibility 0s 0s,
    background-color 300ms var(--ease-out);
}

/* Hovering Buy Fonts floods the whole overlay green */
.menu.is-open:has(.menu__cell--buy:hover) {
  background-color: #21bf30;
}

/* 3×2 grid */
.menu__grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 8px; /* gap + borders on both sides = double-line divider between rows */
  padding-inline: clamp(1.5rem, 3.2vw, 3rem);
  padding-block-start: 56px; /* clear the nav bar */
}

/* Border dividers — exact Figma pattern, full white.
   Row 1 has border-bottom, row 2 has border-top.
   The 8px row gap between them creates the double-line effect.
   Col 1 has border-right, col 3 has border-left (col 2 has none).
   Column gaps create the narrow black strip beside each line. */
.menu__cell:nth-child(1),
.menu__cell:nth-child(2),
.menu__cell:nth-child(3) { border-bottom: 1px solid #fff; }

.menu__cell:nth-child(4),
.menu__cell:nth-child(5),
.menu__cell:nth-child(6) { border-top: 1px solid #fff; }

.menu__cell:nth-child(1),
.menu__cell:nth-child(4) { border-right: 1px solid #fff; }

.menu__cell:nth-child(3),
.menu__cell:nth-child(6) { border-left: 1px solid #fff; }

/* Cell base */
.menu__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5em;
  text-decoration: none;

  /* Closed: invisible + shifted down */
  opacity: 0;
  transform: translateY(0.35em);
  transition:
    opacity  200ms var(--ease-out),
    transform 200ms var(--ease-out);
}

/* Open: staggered slide-up */
.menu.is-open .menu__cell {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity  500ms var(--ease-out),
    transform 500ms var(--ease-out);
}

.menu.is-open .menu__cell:nth-child(1) { transition-delay:  55ms; }
.menu.is-open .menu__cell:nth-child(2) { transition-delay: 100ms; }
.menu.is-open .menu__cell:nth-child(3) { transition-delay: 145ms; }
.menu.is-open .menu__cell:nth-child(4) { transition-delay: 190ms; }
.menu.is-open .menu__cell:nth-child(5) { transition-delay: 235ms; }
.menu.is-open .menu__cell:nth-child(6) { transition-delay: 280ms; }

/* Hover spotlight — hovered cell stays bright, siblings dim.
   Explicit 0s delay overrides the stagger delay above. */
.menu.is-open .menu__grid:hover .menu__cell {
  opacity: 0.25;
  transition: opacity 250ms var(--ease-out) 0s;
}
.menu.is-open .menu__grid:hover .menu__cell:hover {
  opacity: 1;
  transition: opacity 250ms var(--ease-out) 0s;
}

/* Item label — sized to the cell, not the viewport.
   Each cell is an inline-size container, so 100cqi is its content
   box (padding already removed). The widest label, "Buy Fonts" in
   Exemplar Sans Medium, measures 5.15em wide; dividing by 5.5 is
   that plus breathing room, giving the largest size at which every
   label still fits on one line. Re-measure --menu-widest if the
   labels change. min() caps it so wide desktop cells stay sane. */
.menu__cell {
  container-type: inline-size;
}

.menu__item {
  --menu-widest: 5.5;
  /* Centre the letterforms, not the line box. These labels are all-caps,
     so the line box's descender space sits unused under the baseline and
     `align-items: center` reads ~2px low. Trimming to cap-height/baseline
     gives the flex centring the right box. Browsers without text-box
     support simply keep the untrimmed box. */
  text-box: trim-both cap alphabetic;
  font-family: var(--font-display);
  font-size: min(4.5rem, calc(100cqi / var(--menu-widest)));
  font-weight: 400;
  text-transform: uppercase;
  color: #fff;
  line-height: 1.1;
  text-align: center;
}

/* Buy Fonts — Exemplar Sans Medium, green */
.menu__cell--buy .menu__item {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-weight: 500;
  color: #21bf30;
  transition: color 250ms var(--ease-out);
}

/* When the overlay floods green, the label flips to white */
.menu.is-open:has(.menu__cell--buy:hover) .menu__cell--buy .menu__item {
  color: #fff;
}

/* Footer strip */
.menu__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 1.25rem;
  padding-inline: clamp(1.5rem, 0, 3rem);
  margin: 0 3.2vw;
  border-top: 1px solid white;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.5);
  opacity: 0;
  transform: translateY(0.4em);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}

.menu.is-open .menu__footer {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
  transition-delay: 330ms;
}

/* --static: render menu as an in-flow footer (no overlay behaviour) */
.menu--static {
  position: static;
  min-height: 100vh;
  opacity: 1;
  visibility: visible;
  pointer-events: all;
  z-index: auto;
  transition: none;
}

.menu--static .menu__grid {
  padding-block-start: 0;
  padding-inline: var(--container-gutter);
}

.menu--static .menu__footer {
  margin-inline: 0;
  padding-inline: var(--container-gutter);
}

.menu--static .menu__cell {
  opacity: 1;
  transform: none;
  transition: opacity 250ms var(--ease-out);
}

.menu--static .menu__footer {
  opacity: 1;
  transform: none;
  transition: none;
}

.menu--static .menu__grid:hover .menu__cell {
  opacity: 0.25;
  transition: opacity 250ms var(--ease-out);
}

.menu--static .menu__grid:hover .menu__cell:hover {
  opacity: 1;
}

/* ── Mobile: vertical stack ──────────────────────────────── */
@media (max-width: 768px) {
  .menu__grid {
    grid-template-columns: 1fr;
    grid-template-rows: repeat(6, 1fr);
    padding-inline: var(--container-gutter);
    /* No double-line divider here — the borders below collapse to a
       single border-bottom, so the desktop 8px gap would land entirely
       between a rule and the next label, giving every row ~5px more air
       above than below. Zero it so each label sits centred on its rule. */
    gap: 0;
  }

  /* Reset desktop borders, single divider between rows */
  .menu__cell:nth-child(n) {
    border: none;
    border-bottom: 1px solid #fff;
  }
  .menu__cell:last-child {
    border-bottom: none;
  }

  /* Stays on one line: the three spans measure 291px at the xs floor,
     inside the 343px column. space-between (inherited) spreads them. */
  .menu__footer {
    gap: var(--space-sm);
    font-size: var(--text-xs);
  }
}

footer .exlibris {
  height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Only the mark + years are clickable/hoverable — inline-flex shrinks
   the link to its content instead of stretching across the footer. */
footer .exlibris__link {
  display: inline-flex;
  align-items: center;
  color: inherit;
  text-decoration: none;
  transition: opacity var(--duration-fast) var(--ease-out);
}

footer .exlibris__link:hover {
  opacity: 0.6;
}

footer .exlibris p {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
}

footer .exlibris__mark {
  display: block;
  height: 100px;
  width: 100px;
  margin-inline: 0.5em;
}

footer a {
  text-decoration: underline;
}

footer a:hover {
  text-decoration: none;
}

/* ----------------------------------------------------------
   HERO
---------------------------------------------------------- */
.hero {
  position: relative;
  height: 100vh;
  background: #000; /* fallback while video loads */
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.hero__video-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hero__video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 177.78vh;
  height: 56.25vw;
  min-width: 100%;
  min-height: 100%;
  transform: translate(-50%, -50%);
  border: none;
  pointer-events: none;
  background-image: url("../assets/images/background-loader.gif");
  background-repeat: repeat;
  background-color: black;
  background-position: center center;
  background-size: 25px;
}

.hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 3vh, 2.5rem);
  width: 100%;
  padding-inline: var(--container-gutter);
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  padding-bottom: 7.5vh;
  /* font-size set dynamically by hero.ts to fill container width — stay
     hidden until it's been sized once, so the first paint doesn't flash
     it at the browser-default size before the fit runs. */
  visibility: hidden;
}

.hero__title-line2 {
  display: inline;
}

@media (max-width: 768px) {
  .hero__title-space {
    display: none;
  }

  .hero__title-line2 {
    display: block;
  }
}

.hero__body {
  position: absolute;
  z-index: 1;
  bottom: var(--container-gutter);
  left: var(--container-gutter);
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  line-height: 1.4;
  text-align: left;
  color: #fff;
  max-width: 26em;
}

.hero__body-lead {
  text-transform: uppercase;
}

/* ----------------------------------------------------------
   TYPE SELECTOR
---------------------------------------------------------- */
.type-selector {
  min-height: 100svh;
  background-color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.type-selector__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 56px;
  width: min(1317px, 100%);
  padding-inline: var(--container-gutter);
}

.type-selector__controls {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
}

.type-selector__name {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: #fff;
  padding: var(--space-xs);
}

.type-selector__group {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.type-selector__btn {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: #fff;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: var(--space-xs);
  cursor: pointer;
  opacity: 0.5;
  transition:
    opacity var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.type-selector__btn.is-active {
  opacity: 1;
  border-color: rgba(255, 255, 255, 0.15);
}

.type-selector__btn:hover:not(.is-active) {
  opacity: 0.75;
}

.type-selector__display {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  width: 100%;
  font-family: var(--font-display);
  font-size: 72px;
  text-align: center;
  color: #fff;
}

.type-selector__row--upper {
  text-transform: uppercase;
}

@media (max-width: 768px) {
  .type-selector__inner {
    gap: var(--space-2xl);
  }

  .type-selector__controls {
    flex-direction: column;
    gap: var(--space-md);
  }

  .type-selector__display {
    font-size: clamp(24px, 8vw, 72px);
  }
}

.type-selector__size-input {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: #fff;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: var(--radius-sm);
  padding: var(--space-xs);
  width: 4.5ch;
  text-align: center;
  outline: none;
  /* hide browser spinner arrows */
  appearance: textfield;
  -moz-appearance: textfield;
}

.type-selector__size-input::-webkit-inner-spin-button,
.type-selector__size-input::-webkit-outer-spin-button {
  appearance: none;
}

/* ----------------------------------------------------------
   QUOTES
---------------------------------------------------------- */
.quotes {
  height: 100vh;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  user-select: none;
}

.quotes__progress {
  position: absolute;
  top: 56px;
  left: var(--container-gutter);
  right: var(--container-gutter);
  display: flex;
  gap: 4px;
  pointer-events: none;
}

.quotes__bar {
  flex: 1;
  height: 2px;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 1px;
  overflow: hidden;
}

.quotes__bar-fill {
  height: 100%;
  width: 0%;
  background: #fff;
}

.quotes__stage {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-inline: var(--container-gutter);
  text-align: center;
}

.quotes__meta {
  position: absolute;
  bottom: clamp(3rem, 6vh, 5rem);
  left: var(--container-gutter);
  right: var(--container-gutter);
  display: flex;
  justify-content: center;
}

.quotes__text {
  color: #fff;
  font-family: var(--font-display);
}

.quotes__meta {
  align-items: center;
  gap: 24px;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
}

.quotes__source {
  color: rgba(255, 255, 255, 0.5);
}

.quotes__spec {
  color: rgba(255, 255, 255, 1)
}

.quotes__ornament {
  color: rgba(255, 255, 255, 0.5);
  font-family: var(--font-display);
  font-size: 10px;
}

/* Nav hint: pointer on hover, split cursor logic via JS */
.quotes[data-nav="prev"] { cursor: w-resize; }
.quotes[data-nav="next"] { cursor: e-resize; }

@media (max-width: 768px) {
  /* The bar sits on the nav's bottom edge — exactly where .nav::after
     draws its rule — so it keeps the same distance from the nav labels
     that the border has when it's visible. Inherits top: 56px (the nav
     height); no mobile override. */

  .quotes__stage {
    gap: var(--space-xl);
  }

  /* Stacked like a figcaption: no gap, spacing comes from line-height.
     bottom is roughly half the desktop clamp — sits closer to the edge
     on a phone. */
  .quotes__meta {
    bottom: clamp(1.5rem, 3vh, 3rem);
    flex-direction: column;
    gap: 0;
    line-height: 1.4;
  }

  .quotes__ornament {
    display: none;
  }
}

/* --- Transitions --- */

.quotes__text {
  opacity: 0;
  transform: translateY(0.425em);
  transition: opacity 1000ms var(--ease-out), transform 1000ms var(--ease-out);
}

.quotes__meta {
  opacity: 0;
  transform: translateY(3em);
  transition: opacity 1000ms var(--ease-out), transform 1000ms var(--ease-out);
  transition-delay: 150ms;
}

.quotes__text.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.quotes__meta.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ----------------------------------------------------------
   FIG-SLIDER — inline image carousel inside .text__body
   Same progress-bar pattern as .quotes
---------------------------------------------------------- */
.fig-slider {
  position: relative;
  margin: 0 0 1em;
  user-select: none;
  cursor: pointer;
}

.fig-slider__progress {
  position: absolute;
  top: 8px;
  left: 8px;
  right: 8px;
  display: flex;
  gap: 4px;
  pointer-events: none;
  z-index: 1;
}

.fig-slider__bar {
  flex: 1;
  height: 2px;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 1px;
  overflow: hidden;
}

.fig-slider__bar-fill {
  height: 100%;
  width: 0%;
  background: #fff;
}

.fig-slider__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 4px;
}

.fig-slider__stage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
}

.fig-slider__stage img.is-active {
  opacity: 1;
}

.fig-slider[data-nav="prev"] { cursor: w-resize; }
.fig-slider[data-nav="next"] { cursor: e-resize; }

/* Exact-ratio variant — no cropping, respects native image proportions */
.fig-slider--native .fig-slider__stage img {
  object-fit: contain;
}
.fig-slider--native .fig-slider__stage {
  aspect-ratio: 1200 / 1699;
}

/* Bézier inspection variant — 4/5 frame holding inline SVGs generated from
   the font (BezierGlyphs.astro). Every SVG shares the same viewBox height
   (ascender→descender), and preserveAspectRatio centers it in the frame like
   object-fit: contain — so all glyphs render at one em scale, baselines
   aligned, regardless of the frame's size. */
.fig-slider--bezier .fig-slider__stage {
  aspect-ratio: 4 / 5;
}
.fig-slider__stage svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
}
.fig-slider__stage svg.is-active {
  opacity: 1;
}

/* Dark-UI variant — for sliders on light/white images */
.fig-slider--dark .fig-slider__bar {
  background: rgba(0, 0, 0, 0.15);
}
.fig-slider--dark .fig-slider__bar-fill {
  background: #000;
}

/* ----------------------------------------------------------
   VIDEO SECTION
---------------------------------------------------------- */
/* ----------------------------------------------------------
   VIDEO SECTION
   Full-viewport-height. Desktop: 3-col × 3-row CSS grid —
   brackets pin to section edges, card + asides float centre.
   Mobile: flex column, same bracket-at-edge logic via margin-auto.
   All decorative lines are pure CSS borders, no SVG.
---------------------------------------------------------- */

/* Desktop grid
   Columns: [left-aside] [card-column] [right-aside]
   Rows:    [top-bracket] [centred-content] [bottom-bracket]
   Asides span all 3 rows (grid-row: 1/-1) and self-centre. */
.video-section {
  min-height: 100vh;
  background: #fff;
  color: #000;
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: auto 1fr auto;
  padding-inline: var(--container-gutter);
  padding-block: 32px;
}

.video-section__top-rule    { grid-column: 2; grid-row: 1; align-self: start; }
.video-section__aside--left { grid-column: 1; grid-row: 1 / -1; align-self: center; text-align: center; }
.video-section__card        { grid-column: 2; grid-row: 2; align-self: center; }
.video-section__aside--right{ grid-column: 3; grid-row: 1 / -1; align-self: center; text-align: center; }
.video-section__bottom-rule { grid-column: 2; grid-row: 3; align-self: end; }

/* Text asides */
.video-section__aside {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  line-height: 1.4;
  color: #000;
  margin: 0;
}

.video-section__aside span {
  text-transform: uppercase;
}

/* ---- Top bracket ---- */
/* Full-width top border spanning the card column,
   with two inner tabs hanging down from it. */
.video-section__top-rule {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  height: 32px;
  border-top: 1px solid #000;
}

/* Left tab: just a bottom border */
.video-section__tl {
  width: 96px;
  height: 24px;
  border-bottom: 1px solid #000;
}

/* Right corner: bottom + left border */
.video-section__tr {
  width: 96px;
  height: 24px;
  border-bottom: 1px solid #000;
  border-left: 1px solid #000;
}

/* ---- Card ---- */
.video-section__card {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
}

.video-section__media {
  position: absolute;
  inset: 0;
}

.video-section__media img,
.video-section__media video,
.video-section__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: none;
  pointer-events: none;
}

.video-section__overlay {
  position: absolute;
  inset: auto 0 0 0;
  height: 55%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent);
  pointer-events: none;
}

.video-section__info {
  position: absolute;
  bottom: 24px;
  left: 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.video-section__play {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  line-height: 0;
}

.video-section__play-icon {
  width: 18px;
  height: auto;
}

.video-section__meta {
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  gap: 2px;
}

.video-section__title {
  font-size: 14px;
  color: #fff;
  line-height: 1.3;
}

.video-section__duration {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.3;
}

/* ---- Bottom bracket marks ---- */
/* Double-line corner marks: nested L-shapes via ::before pseudo-element. */
.video-section__bottom-rule {
  display: flex;
  justify-content: space-between;
}

.video-section__bl,
.video-section__br {
  position: relative;
  width: 96px;
  height: 48px;
}

.video-section__bl {
  border-left: 1px solid #000;
  border-bottom: 1px solid #000;
}

.video-section__bl::before {
  content: '';
  position: absolute;
  top: 8px;
  left: 8px;
  bottom: 8px;
  right: 0;
  border-left: 1px solid #000;
  border-bottom: 1px solid #000;
}

.video-section__br {
  border-right: 1px solid #000;
  border-bottom: 1px solid #000;
}

.video-section__br::before {
  content: '';
  position: absolute;
  top: 8px;
  right: 8px;
  bottom: 8px;
  left: 0;
  border-right: 1px solid #000;
  border-bottom: 1px solid #000;
}

/* ---- Mobile ---- */
/* Switch to flex column. Brackets stay at edges via margin-top: auto. */
@media (max-width: 767px) {
  .video-section {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    padding-block: 32px;
    gap: 0;
  }

  /* Order: top-bracket → [gap] → "Filmed in" → card → "Stone carving" → [gap] → bottom-bracket */
  .video-section__top-rule     { order: 1; }
  .video-section__aside--left  { order: 2; text-align: center; margin-top: auto; padding-bottom: 20px; }
  .video-section__card         { order: 3; border-radius: 6px; }
  .video-section__aside--right { order: 4; text-align: center; padding-top: 20px; }
  .video-section__bottom-rule  { order: 5; margin-top: auto; }

  .video-section__info {
    bottom: 16px;
    left: 16px;
  }
}

/* ----------------------------------------------------------
   HERO
---------------------------------------------------------- */
.section--hero {
  min-height: 100svh;
  display: flex;
  align-items: center;
}

/* ----------------------------------------------------------
   SPECIMEN
---------------------------------------------------------- */
.section--specimen {
  background-color: #0f0f0f;
  color: #f0f0f0;
  padding-block: 0;
  overflow: hidden;
}

/* Two-column layout: glyph hero | charset rows */
.specimen__inner {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  min-height: 80vh;
}

/* Left: large numeral */
.specimen__hero-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4xl) var(--space-3xl);
}

.specimen__numeral {
  font-size: clamp(18rem, 28vw, 36rem);
  line-height: 0.85;
  color: #f0f0f0;
  user-select: none;
  letter-spacing: -0.04em;
}

/* Vertical divider */
.specimen__divider {
  background-color: rgba(255, 255, 255, 0.15);
  align-self: stretch;
}

/* Right: stacked character rows */
.specimen__charset {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-4xl) var(--space-3xl);
  gap: 0;
}

.specimen__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-block: var(--space-xl);
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.specimen__row:first-child {
  border-top: 1px solid rgba(255, 255, 255, 0.15);
}

.specimen__row-label {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.15);
}

.specimen__row-glyphs {
  font-size: clamp(1.1rem, 1.6vw, 1.5rem);
  line-height: 1.4;
  color: #f0f0f0;
  word-spacing: 0.15em;
  letter-spacing: 0.02em;
}

/* ----------------------------------------------------------
   SPECIMEN — Tablet ≤ 1024px
---------------------------------------------------------- */
@media (max-width: 1024px) {
  .specimen__numeral {
    font-size: clamp(10rem, 22vw, 20rem);
  }

  .specimen__hero-glyph,
  .specimen__charset {
    padding: var(--space-3xl) var(--space-2xl);
  }
}

/* ----------------------------------------------------------
   SPECIMEN — Mobile ≤ 768px
   Stack vertically: numeral on top, charset below
---------------------------------------------------------- */
@media (max-width: 768px) {
  .specimen__inner {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1px auto;
  }

  .specimen__divider {
    width: 100%;
    height: 1px;
    background-color: rgba(255, 255, 255, 0.15);
  }

  .specimen__hero-glyph {
    padding: var(--space-4xl) var(--space-xl);
    min-height: 40vw;
  }

  .specimen__numeral {
    font-size: clamp(8rem, 40vw, 14rem);
  }

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

  .specimen__row-glyphs {
    font-size: var(--text-base);
    word-spacing: 0.1em;
  }
}

/* ----------------------------------------------------------
   WEIGHTS
---------------------------------------------------------- */
.section--weights {
  /* Weight ramp rows */
}

/* ----------------------------------------------------------
   MEDIA BLOCK — reusable full-bleed section
   Drop in an <img> or <video> with class="media-block__asset".
   Without media the block shows as a dark placeholder.
---------------------------------------------------------- */
.media-block {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  color: #fff;
}

/* Loader frame — a non-fading backdrop carrying the loading GIF. The <img>
   (with .img-fade) fades in on top of it, so the loader stays visible while the
   image decodes. It must be a separate element: opacity on the <img> itself
   would fade away its own background too. Added by <Img loader />. */
.img-frame {
  display: block;
  position: relative;
  overflow: hidden;
  background-color: black;
  background-image: url("../assets/images/background-loader.gif");
  background-repeat: repeat;
  background-position: top left;
}

.media-block__asset {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Default (fill) variant: the frame fills the section, the image fills the frame. */
.media-block > .img-frame {
  position: absolute;
  inset: 0;
}

/* --align-top / --align-bottom: pin the image when using fixed height */
.media-block--align-top     .media-block__asset { object-position: center top; }
.media-block--align-bottom  .media-block__asset { object-position: center bottom; }
.media-block--align-b25     .media-block__asset { object-position: center 75%; }

/* --2col / --4col / --6col / --8col: constrain image to N grid columns, centered */
.media-block--2col,
.media-block--4col,
.media-block--6col,
.media-block--8col {
  --_col-padding-block: clamp(4rem, 8vh, 7rem);
  height: auto;
  padding-block: var(--_col-padding-block);
}

/* In-flow variants (--2col–8col, --ratio, --label-below): the frame becomes a
   normal-flow box and the image flows inside it, so the image's natural ratio
   sets the height (and the loader fills exactly the image's box, not the block). */
.media-block--2col  .img-frame,
.media-block--4col  .img-frame,
.media-block--6col  .img-frame,
.media-block--8col  .img-frame,
.media-block--ratio       .img-frame,
.media-block--label-below .img-frame {
  position: relative;
  inset: auto;
  height: auto;
}

.media-block--2col  .media-block__asset,
.media-block--4col  .media-block__asset,
.media-block--6col  .media-block__asset,
.media-block--8col  .media-block__asset,
.media-block--ratio       .media-block__asset,
.media-block--label-below .media-block__asset {
  position: relative;
  inset: auto;
  width: 100%;
  height: auto;
  object-fit: unset;
}

/* Column variants size the frame to N grid columns, centered. */
.media-block--2col .img-frame,
.media-block--4col .img-frame,
.media-block--6col .img-frame,
.media-block--8col .img-frame {
  width: var(--_asset-width);
  margin-inline: auto;
}

.media-block--2col { --_asset-width: calc(16.667% - var(--grid-gap) * 5 / 6); }
.media-block--4col { --_asset-width: calc(33.333% - var(--grid-gap) * 2 / 3); }
.media-block--6col { --_asset-width: calc(50%     - var(--grid-gap) / 2); }
.media-block--8col { --_asset-width: calc(66.667% - var(--grid-gap) / 3); }

/* --ratio: image natural proportions set the section height */
.media-block--ratio {
  height: auto;
}

.media-block__label {
  position: absolute;
  top: var(--container-gutter);
  left: var(--container-gutter);
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  line-height: 1.4;
  gap: 0;
}

.media-block--label-bottom-right .media-block__label {
  top: auto;
  left: auto;
  bottom: var(--container-gutter);
  right: var(--container-gutter);
  text-align: right;
}

/* --label-center-left: vertically centered on the left edge */
.media-block--label-center-left .media-block__label {
  top: 50%;
  left: var(--container-gutter);
  bottom: auto;
  right: auto;
  transform: translateY(-50%);
}

/* --label-center-left: vertically centered on the left edge */
.media-block--label-bottom-left .media-block__label {
  top: auto;
  right: auto;
  bottom: var(--container-gutter);
  left: var(--container-gutter);
  text-align: left;
}

/* Column variants pad the frame off the block's top/bottom edges by
   --_col-padding-block (not --container-gutter), so a bottom-anchored label
   using the plain gutter lands short of the frame's actual bottom edge,
   in the leftover padding space below the image. Match the frame's real
   inset so the caption sits flush with the image instead. */
.media-block--2col.media-block--label-bottom-right .media-block__label,
.media-block--4col.media-block--label-bottom-right .media-block__label,
.media-block--6col.media-block--label-bottom-right .media-block__label,
.media-block--8col.media-block--label-bottom-right .media-block__label,
.media-block--2col.media-block--label-bottom-left .media-block__label,
.media-block--4col.media-block--label-bottom-left .media-block__label,
.media-block--6col.media-block--label-bottom-left .media-block__label,
.media-block--8col.media-block--label-bottom-left .media-block__label {
  bottom: var(--_col-padding-block);
}

/* --label-below: caption flows outside the image, below and left-aligned */
.media-block--label-below {
  height: auto;
  overflow: visible;
  display: flex;
  flex-direction: column;
}

.media-block--label-below .media-block__label {
  position: static;
  top: auto;
  left: auto;
  padding-top: 12px;
  padding-bottom: var(--container-gutter);
  padding-inline: var(--container-gutter);
}

.media-block__title {
  //text-transform: uppercase;
  //letter-spacing: 0.05em;
}

.media-block__caption {
  opacity: 0.5;
}

/* Mobile: every media-block collapses to the --label-below pattern — the image
   spans the full viewport width at its natural ratio (column variants
   included) and the label leaves the overlay to flow below the image. */
@media (max-width: 768px) {
  .media-block {
    height: auto;
    overflow: visible;
    display: flex;
    flex-direction: column;
    padding-block: 0;
  }

  .media-block > .img-frame {
    position: relative;
    inset: auto;
    width: 100%;
    height: auto;
    margin-inline: 0;
  }

  .media-block .media-block__asset {
    position: relative;
    inset: auto;
    width: 100%;
    height: auto;
    object-fit: unset;
  }

  .media-block .media-block__label {
    position: static;
    transform: none;
    text-align: left;
    padding-top: 12px;
    padding-bottom: var(--container-gutter);
    padding-inline: var(--container-gutter);
  }
}

/* --fit: give the image a fixed height on mobile instead of letting
   it run at its natural ratio, and crop it to fill that box. Height is
   tunable per block via --media-fit-height.
   Must sit after the mobile block above — same specificity, so source
   order is what wins. */
@media (max-width: 768px) {
  .media-block--fit > .img-frame {
    height: var(--media-fit-height, 45vh);
    flex: 0 0 auto;
  }

  .media-block--fit .media-block__asset {
    height: 100%;
    object-fit: cover;
  }

  /* --label-overlay: opt out of the stacked-below label for a block
     that keeps its desktop overlay on mobile too. Only worth it on a
     tall hero, where there's room for the label to sit over the image
     without fighting it. Mirrors --label-center-left. */
  .media-block--label-overlay .media-block__label {
    position: absolute;
    top: 50%;
    left: var(--container-gutter);
    right: auto;
    bottom: auto;
    transform: translateY(-50%);
    padding: 0;
  }
}

/* ----------------------------------------------------------
   EDITORIAL
---------------------------------------------------------- */
.text {
  background: #000;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(4rem, 8vh, 7rem);
}

.text--full {
  min-height: 100vh;
}

.text__body {
  padding-inline: var(--container-gutter);
  padding-block: clamp(1.5rem, 3vh, 2rem);
  max-width: 480px;
  margin: 0 auto;
}

.text__body p, .text__body h3, .text__body ul {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: clamp(14px, 1.2vw, 16px);
  font-weight: normal;
  color: #fff;
  line-height: 1.6;
  margin: 0 0 1em;
}

.text__body h3 {
  margin: 0;
}

.text__body li {
  opacity: 0.5
}

/* Mobile: the column is left-aligned rather than centred, and its
   edge is --container-gutter — the same inset the media-block captions
   use — so the prose starts on the same line as every image caption on
   the page. Figures then run the full width of that column, and the
   prose carries the extra inset on the right instead. That keeps the
   measure roughly where it was while anchoring everything left.
   Figcaptions stay on the xs step and align with their image. */
@media (min-width: 769px) and (max-width: 1024px) {
  .text__body {
    max-width: 360px;
  }
}

@media (max-width: 768px) {
  .text__body {
    margin-inline: 0;
    padding-inline: var(--container-gutter);
  }

  .text__body p, .text__body h3, .text__body ul {
    font-size: 1rem;
    padding-right: var(--text-right-inset, 2.5rem);
  }
}

.text__body figure {
  margin: 0 0 1em;
}

.text__body figure img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: cover;
  border-radius: 4px;
}

.text__body figcaption {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.4;
  padding-top: 0.5em;
}

/* ----------------------------------------------------------
   TEXT ARROWS  (experimental — safe to remove)
   Two arrows flanking each .text__body. They rest aligned with
   the first line, lock at the viewport centre (top: 50vh) while
   the reader scrolls, then release at the bottom of the block —
   the sticky element is bounded by its .text__body, so it stops
   "pointing" once the paragraph has passed.
   Injected by src/modules/textArrows.ts. To remove the feature:
   delete that file, its init in src/main.ts, and this block.
---------------------------------------------------------- */
.text__body { position: relative; } /* containing block for the arrows overlay */

/* Overlay = the sticky "track"'s containing block. Absolutely positioned so it
   never shifts the text. Inset to span first line → last line: top skips the
   block's top padding; bottom skips the bottom padding + the last line's
   trailing space so the arrows release ON the last line, not below the div. */
.text-arrows {
  position: absolute;
  left: var(--container-gutter);
  right: var(--container-gutter);
  top: clamp(1.5rem, 3vh, 2rem);
  bottom: calc(clamp(1.5rem, 3vh, 2rem) + 2.4em);
  z-index: 2;
  pointer-events: none;
  font-size: clamp(14px, 1.2vw, 16px); /* match .text__body p, so em aligns to the line */
  --text-arrow-gap: clamp(1.5rem, 4vw, 3rem);
}

.text-arrows__track {
  position: sticky;
  top: 50vh;
  height: 0;               /* zero-height: pins its centre, bounded by the overlay */
}

.text-arrows__arrow {
  position: absolute;
  top: 0.8em;              /* half a line-height (1.6) → centres on the row */
  line-height: 0;
}

.text-arrows__arrow--left {
  left: calc(-1 * var(--text-arrow-gap));
  transform: translate(-100%, -50%);
}

.text-arrows__arrow--right {
  right: calc(-1 * var(--text-arrow-gap));
  transform: translate(100%, -50%) rotate(180deg);
}

/* Narrow screens: gutters vanish, so the arrows have nowhere to sit. */
@media (max-width: 768px) {
  .text-arrows { display: none; }
}

.text a {
  text-decoration: underline;
}

.text a:hover {
  text-decoration: none;
}

/* ----------------------------------------------------------
   CREDITS — dot-leader rows, old-school film-credits style.
   The left label flexes to fill the line and trails a run of
   periods; overflow:hidden clips them right before the name.
   align-items:baseline keeps the dots sitting on the baseline.
---------------------------------------------------------- */
.credits {
  background: #000;
  padding-block: clamp(4rem, 8vh, 7rem);
  padding-inline: var(--container-gutter);
}

.credits__list {
  max-width: 480px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.credits__row {
  display: flex;
  align-items: baseline;
  margin: 0;
}

.credits__row + .credits__row {
  margin-top: 0.75em;
}

/* left label: grows to fill, trails periods, clips at the name */
.credits__role {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: clamp(13px, 1.1vw, 15px);
  color: rgba(255, 255, 255, 0.55);
}

.credits__role::after {
  content: " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
  color: rgba(255, 255, 255, 0.3);
}

/* right item: natural width, never shrinks */
.credits__name {
  flex: 0 0 auto;
  padding-left: 0.75em;
  margin: 0;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: clamp(13px, 1.1vw, 15px);
  color: #fff;
}

/* ----------------------------------------------------------
   VIDEO
---------------------------------------------------------- */
.section--video {
  background-color: var(--color-surface);
}

.video__player {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}

/* ----------------------------------------------------------
   GALLERY
---------------------------------------------------------- */
.section--gallery {
  /* Image grid */
}

.gallery__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gap);
}

.gallery__item {
  cursor: pointer;
  overflow: hidden;
}

.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slow) var(--ease-out);
}

.gallery__item:hover img {
  transform: scale(1.04);
}

@media (max-width: 1024px) {
  .gallery__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .gallery__grid {
    grid-template-columns: 1fr;
  }
}

/* ----------------------------------------------------------
   CTA
---------------------------------------------------------- */
.section--cta {
  text-align: center;
}

/* ----------------------------------------------------------
   LIGHTBOX
---------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background-color: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
}

.lightbox__media {
  max-width: 90vw;
  max-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lightbox__media img,
.lightbox__media video {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
}

.lightbox__close {
  position: absolute;
  top: var(--space-xl);
  right: var(--space-xl);
  font-size: var(--text-2xl);
  color: #fff;
  line-height: 1;
}

.lightbox__prev,
.lightbox__next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-size: var(--text-2xl);
  color: #fff;
  padding: var(--space-md);
}

.lightbox__prev { left: var(--space-xl); }
.lightbox__next { right: var(--space-xl); }

/* ----------------------------------------------------------
   VIDEO LIGHTBOX — modal player for the video section card
---------------------------------------------------------- */
.video-lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 300ms var(--ease-out), visibility 0s 300ms;
}

.video-lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 300ms var(--ease-out), visibility 0s 0s;
}

.video-lightbox__player {
  width: 100vw;
  max-height: 100vh;
  aspect-ratio: 16 / 9;
}

/* The full film plays through a Vimeo embed; its own player chrome (white
   accent, minimal controls) is configured via the iframe src query params. */
.video-lightbox__player iframe {
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
}

/* Anchored to the .video-lightbox overlay (fixed, inset:0) so it pins to the
   window's top-right corner regardless of the video's letterboxing. */
.video-lightbox__close {
  position: absolute;
  top: 24px;
  right: 24px;
  z-index: 2;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 8px;
  line-height: 0;
  opacity: 0.5;
  transition: opacity 150ms var(--ease-out);
}

.video-lightbox__close:hover {
  opacity: 1;
}

/* ----------------------------------------------------------
   STATEMENT FINALE — centers the film below the closing line.
---------------------------------------------------------- */
.statement__finale {
  margin: clamp(2rem, 7.5vh, 3.5rem);
}

/* ----------------------------------------------------------
   MINI PLAYER — preview card that opens the full-screen video
   lightbox. Loops a muted preview; on hover it lifts and
   reveals a centered play triangle.
---------------------------------------------------------- */
.mini-player {
  position: relative;
  width: clamp(200px, 36vw, 400px);
  aspect-ratio: 16 / 9;
  padding: 0;
  border-radius: var(--radius-sm);
  overflow: hidden;
  cursor: pointer;
  background: #000;
  transition: transform var(--duration-xslow) var(--ease-out);
}

.mini-player__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

/* Scrim — a soft gradient at the base keeps the label legible at rest;
   it darkens uniformly on hover. */
.mini-player__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 55%);
  transition: background var(--duration-base) var(--ease-out);
  pointer-events: none;
}

.mini-player__icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0.8);
  transition:
    opacity var(--duration-slow) var(--ease-out),
    transform var(--duration-slow) var(--ease-out);
  pointer-events: none;
}

.mini-player__label {
  position: absolute;
  left: 16px;
  bottom: 14px;
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  line-height: 1;
  color: #fff;
  transition: opacity var(--duration-slow) var(--ease-out);
  pointer-events: none;
}

.mini-player__label-time {
  opacity: 0.5;
}

/* Hover / focus — lift the card, darken the scrim, reveal the centered
   play triangle, and recede the resting label. */
.mini-player:hover,
.mini-player:focus-visible {
  transform: translateY(-4px) scale(1.03);
  outline: none;
}

.mini-player:hover .mini-player__scrim,
.mini-player:focus-visible .mini-player__scrim {
  background: rgba(0, 0, 0, 0.4);
}

.mini-player:hover .mini-player__icon,
.mini-player:focus-visible .mini-player__icon {
  opacity: 1;
  transform: scale(1);
}

.mini-player:hover .mini-player__label,
.mini-player:focus-visible .mini-player__label {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .mini-player,
  .mini-player__scrim,
  .mini-player__icon,
  .mini-player__label {
    transition: none;
  }
  .mini-player:hover,
  .mini-player:focus-visible {
    transform: none;
  }
}

/* ----------------------------------------------------------
   PAGE PLACEHOLDER
   Temporary full-height holding page for menu destinations.
   Replace with real content as each section is designed.
---------------------------------------------------------- */
.page-placeholder {
  min-height: 100vh;
  background: #fff;
  color: #000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding-inline: var(--container-gutter);
  text-align: center;
}

.page-placeholder__title {
  font-family: var(--font-display);
  font-size: clamp(4rem, 10vw, 10rem);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1;
}

.page-placeholder__sub {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(0, 0, 0, 0.4);
  text-transform: uppercase;
}

/* ----------------------------------------------------------
   STATEMENT — intro text block (index page, module 2)
---------------------------------------------------------- */
.statement {
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: clamp(4rem, 25vh, 15rem);
}

/* Tighter bottom when flowing directly into the type tester */
.statement:has(+ .examples) {
  padding-block-end: clamp(2rem, 12.5vh, 7.5rem);
}

.statement--full {
  min-height: 100vh;
}

.statement__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 48px;
  max-width: 937px;
  width: 100%;
  text-align: center;
}

.statement__body {
  font-family: var(--font-display);
  font-size: clamp(1.875rem, 3.33vw, 3rem); /* floor = 30px */
  font-weight: 400;
  line-height: 1.2;
  color: #fff;
}

.statement__body p:not(.caption) {
  max-width: 40ch;
}

.statement__body p + p {
  margin-top: 24px;
}

/* The forced 2×2 break (.lang-break, inserted by languageCycle.ts) is
   mobile-only — desktop has room for all four names on one line. */
.lang-break {
  display: none;
}

/* Mobile: shorten the vertical breathing room, pull the text off
   the screen edges, and step up to Medium — Regular gets fragile
   at this size on a phone. */
@media (max-width: 768px) {
  .statement {
    padding-block: clamp(4rem, 15vh, 15rem);
  }

  .statement__body {
    padding-inline: 0.75em;
    font-weight: 500;
  }

  .lang-break {
    display: inline;
  }

  /* Reserve two full lines — the forced break above always produces
     two, but without a fixed height the swap between shorter/longer
     name pairs still makes the row (and everything below it) jump. */
  [data-language-cycle] {
    min-height: calc(1.2em * 2);
  }

  /* Desktop forces "Sweden," and "but they are for everyone." onto
     separate lines; on mobile the narrower column already wraps
     naturally, and keeping the forced break on top of that produces
     an extra, oddly short line. */
  .statement__break {
    display: none;
  }
}

/* Language cycling — each word is independently animatable */
.lang-slot {
  display: inline-block;
  opacity: 1; /* explicit baseline so the transition always has a from-value */
  overflow: hidden;
  vertical-align: bottom; /* keep baselines stable during width transition */
  transition:
    opacity    600ms var(--ease-out),
    transform  400ms var(--ease-out),
    width      500ms cubic-bezier(0.4, 0, 0.2, 1); /* smooth width morph */
}

.lang-slot--arabic {
  font-family: 'Exemplar Arabic', serif;
}

.statement__link {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  text-decoration: none;
  transition: color 200ms var(--ease-out);
}

/* ----------------------------------------------------------
   HISTORY — editorial text + photo (Hands page)
---------------------------------------------------------- */
.history {
  background: #fff;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
  padding-block: var(--container-gutter);
  padding-inline: var(--container-gutter);
}

.history__grid {
  align-items: start;
}

.history__text {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  line-height: 1.6;
  color: #000;
  padding-top: 4px; /* optical alignment with image */
}

.history__text p + p {
  margin-top: 1.2em;
}

.history__photo {
  width: 100%;
  height: auto;
  display: block;
}

@media (max-width: 768px) {
  .history__photo {
    order: -1;
  }
}

/* ----------------------------------------------------------
   EXAMPLES — Type tester (The End page)
---------------------------------------------------------- */
.examples {
  //min-height: 100vh;
  background: #000;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 72px;
  margin-bottom: 25vh;
  /* Horizontal-only — gap/margin-bottom already handle vertical spacing.
     Without this, .examples__text has no inset and can sit flush against
     the viewport edge at large sizes. */
  padding-inline: var(--container-gutter);
}

.examples__controls {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Thin vertical separator between groups */
.examples__divider {
  width: 1px;
  height: 20px;
  background: rgba(255, 255, 255, 0.15);
  flex-shrink: 0;
}

.examples__group {
  display: flex;
  align-items: center;
  gap: 4px;
}

.examples__label {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
  padding: 8px;
  white-space: nowrap;
}

/* Only the stacked mobile panel needs this one — the desktop bar
   leans on its dividers for grouping. */
.examples__label--script {
  display: none;
}

/* Native OS weight picker — styled to match bordered value box */
.examples__select {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  color: #fff;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  padding: 7px 8px;
  cursor: pointer;
  white-space: nowrap;
}

/* Size input + pt label share one bordered box */
.examples__size-box {
  display: flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  padding: 7px 8px;
  gap: 2px;
}

.examples__size-number {
  background: none;
  border: none;
  color: #fff;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  width: 3ch;
  text-align: right;
  outline: none;
  padding: 0;
  -moz-appearance: textfield;
}

.examples__size-number::-webkit-inner-spin-button,
.examples__size-number::-webkit-outer-spin-button {
  -webkit-appearance: none;
}

.examples__size-unit {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
}


/* Year / Script toggle buttons */
.examples__btn {
  background: none;
  border: 1px solid transparent;  /* reserve space to avoid layout shift */
  border-radius: 4px;
  color: rgba(255, 255, 255, 0.5);
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  padding: 7px 8px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 150ms ease, border-color 150ms ease;
}

.examples__btn:hover {
  color: rgba(255, 255, 255, 0.8);
}

.examples__btn.is-active {
  border-color: rgba(255, 255, 255, 0.15);
  color: #fff;
}

/* Display area — no hard clip; fitText handles sizing */
.examples__display {
  width: 100%;
  overflow: visible;
}

.examples__text {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  display: block;
  text-align: center;
  outline: none;
  cursor: text;
  transition: font-size var(--duration-base) var(--ease-out);
}

/* ── Mobile ───────────────────────────────────────────────
   Once the bar wraps, its dividers can't carry the grouping any
   more, so the controls become a stacked panel: one row per
   group, label left, control right, hairline between — the same
   grammar as .font-overview__row and .credits. Size is dropped:
   the specimen arrives at a designed size, and the controls
   worth having on a phone are the typographic ones.
   1080px (not the usual 768px): the control row's natural flex-wrap
   point is ~1050px (measured live — unwrapped at 1054px, wrapped by
   1048px), so the breakpoint sits above that with margin. Below 768px
   the row would wrap awkwardly (Script alone on its own line) well
   before this stacked layout used to kick in. */
@media (max-width: 1080px) {
  .examples {
    gap: 40px;
    padding-top: 100px;
    justify-content: flex-start;
  }

  .examples__divider {
    display: none;
  }

  .examples__controls {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 0;
  }

  .examples__group {
    justify-content: flex-start;
    padding-block: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.15);
  }

  .examples__group:last-child {
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  }

  /* Size is a desktop instrument — the specimen arrives sized. */
  .examples__group:has(.examples__size-box) {
    display: none;
  }

  .examples__label--script {
    display: block;
  }

  /* The label holds the left edge in a fixed-width column, so every
     row's options start at the same x regardless of row content —
     matching where the Script row's (widest) options land. */
  .examples__label {
    flex: 0 0 116px;
    padding-inline: 0;
  }

  .examples__group > .examples__label + * {
    margin-inline-start: 0;
  }

  /* 44px touch targets. Vertical padding only — the horizontal
     padding is what decides whether a row still fits at 320px. */
  .examples__btn,
  .examples__select {
    padding-block: 11px;
    border-radius: 0;
  }

  /* The row's own hairline (border-top, plus border-bottom on the last
     row) already draws the horizontal divider right at the control's
     top/bottom edge — keeping the control's own top/bottom border too
     doubles up as a slightly-misaligned second line. Drop those two
     sides and let the row divider be the only horizontal line; the
     control's left/right border still marks its width. */
  .examples__select,
  .examples__btn.is-active {
    border-top-color: transparent;
    border-bottom-color: transparent;
  }
}

/* ----------------------------------------------------------
   SHOWCASE — full-width type specimen blocks
   JS (initShowcase) scales each block's text to fill the width.
   Font-size label is written back from the computed size.
   Add a block in HTML; control style via inline attributes on
   .showcase__display (font-weight, font-feature-settings, etc.)
---------------------------------------------------------- */
.showcase {
  background: #000;
  color: #fff;
  padding-block: 3.75em;
  padding-inline: var(--container-gutter);
  overflow-x: clip; /* prevent horizontal scroll without creating a scroll container */
}

/* Info bar: top rule + metadata row */
.showcase__info {
  display: flex;
  align-items: baseline;
  gap: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  padding-top: 12px;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: #fff;
}

/* Secondary metadata — size and feature attrs */
.showcase__font-size,
.showcase__font-attrs {
  opacity: 0.5;
}

/* Display text — JS sets font-size; inline styles set weight/features */
.showcase__display {
  width: 100%;
  overflow: visible; /* allow glyphs to breathe at edges; section clips via overflow-x: clip */
  font-family: 'Exemplar', serif;
  text-align: center;
  padding-bottom: 2.5vh;
}

.showcase__display p {
  margin: 0;
  white-space: nowrap;
  line-height: 1.05; /* headroom for tall glyphs, descenders, and italic swashes */
}

/* Arabic descends lower — needs extra vertical room */
.showcase__display[dir="rtl"] p {
  line-height: 1.15;
}

/* Last block needs no extra bottom padding (section has its own) */
.showcase__block:last-child .showcase__display {
  padding-bottom: 0;
}

/* Light variant — white background, dark text */
.showcase--light {
  background: #fff;
  color: #000;
}

.showcase--light .showcase__info {
  border-top-color: rgba(0, 0, 0, 0.12);
  color: #000;
}

/* Phone: the info bar tightens up, and the specimen gains a little
   breathing room above the line so tall glyphs stay off the rule. */
@media (max-width: 768px) {
  .showcase__info {
    gap: 8px;
  }

  .showcase__display {
    padding-top: 1vh;
  }
}

/* ----------------------------------------------------------
   FONT-OVERVIEW — compact weight specimen
   One row per weight/style: a small UI-sans label on the left,
   a single large line of the display face on the right that runs
   off the edge (clipped) rather than wrapping. Static — weight and
   style are set inline per row; no JS sizing.
---------------------------------------------------------- */
.font--overview {
  background: #000;
  color: #fff;
  padding-block: 3.75em;
  padding-inline: var(--container-gutter);
  overflow-x: clip; /* contain the lines that run past the edge */
}

.font-overview__row {
  display: flex;
  align-items: flex-start;
  gap: clamp(1.5rem, 4vw, 3rem);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
}

.font-overview__row:last-child {
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.font-overview__label {
  flex: 0 0 auto;
  width: clamp(6.5rem, 12vw, 10rem);
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.6);
  padding-top: 0.35em;
}

.font-overview__sample {
  flex: 1 1 auto;
  min-width: 0;            /* allow the flex item to shrink so overflow can clip */
  margin: 0;
  font-family: 'Exemplar', serif;
  font-size: clamp(2rem, 5.5vw, 4.5rem);
  line-height: 1.3;        /* headroom for ascenders, descenders, italic swashes */
  white-space: nowrap;
  overflow: hidden;        /* hard-clip the line at the column edge */
}

/* The wave-scroll bloom (mobile) scales .font-overview__sample-text, not
   the <p> around it — an overflow:hidden box's own clip region scales
   right along with a transform applied to itself, so if the bloom scaled
   the <p> directly the crop line would travel outward with it. Scaling
   only the inner span keeps the <p>'s clip fixed at the column edge. */
.font-overview__sample-text {
  display: inline-block;
}

/* ── Wave (mobile) ────────────────────────────────────────
   Lines near the vertical centre of the screen swell as you
   scroll. src/modules/waveScroll.ts writes --wave (0 → 1) per
   line; everything below is the tuning. Add data-wave to any
   section to opt it in. Scaling (not font-size) keeps this off
   the layout path, so it stays smooth on a phone. */
@media (max-width: 768px) {
  .wave-item {
    --wave: 0;
    --wave-amp: 0.08; /* growth at the peak — 8% */
    --wave-dim: 0.8;  /* opacity at rest */
    transform: scale(calc(1 + var(--wave-amp) * var(--wave)));
    transform-origin: left center;
    opacity: calc(var(--wave-dim) + (1 - var(--wave-dim)) * var(--wave));
  }

  /* Mirrored rows grow from the right edge instead */
  .font--overview--rtl .wave-item {
    transform-origin: right center;
  }
}

/* RTL variant (Arabic): mirror the row — weight labels move to the right,
   the sample fills leftward, and each line reads from the right edge and
   clips off the left page edge (not mid-page). */
.font--overview--rtl .font-overview__row {
  direction: rtl;
}

.font--overview--rtl .font-overview__sample {
  text-align: right;
  line-height: 1.6
}

/* ----------------------------------------------------------
   OPENTYPE FEATURES — stylistic sets compared side by side.
   Same dark canvas as font--overview, but a three-column grid:
   the set label, the sample with the feature off, and the same
   sample with the feature on (font-feature-settings, inline).
---------------------------------------------------------- */
.font--features {
  background: #000;
  color: #fff;
  padding-block: 3.75em;
  padding-inline: var(--container-gutter);
  overflow-x: clip;
}

.font-features__head,
.font-features__row {
  display: grid;
  grid-template-columns: clamp(6.5rem, 12vw, 10rem) 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

.font-features__head {
  padding-bottom: 0.75em;
}

.font-features__head-title,
.font-features__head-state {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.6);
}

.font-features__row {
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  padding-block: 0.6em;
}

.font-features__row:last-child {
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

.font-features__meta {
  display: flex;
  flex-direction: column;
  padding-top: 0.45em;
}

.font-features__set {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
}

.font-features__desc {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.6);
}

.font-features__sample {
  margin: 0;
  min-width: 0;
  font-family: 'Exemplar', serif;
  font-size: clamp(1.5rem, 3.2vw, 2.75rem);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
}

/* Faint gray marker behind each glyph the feature alters. The box-shadow
   spread pads the box a touch around the letter without shifting layout,
   so the two columns stay perfectly aligned. */
.font-features__hl {
  background: rgba(255, 255, 255, 0.15);
  //box-shadow: 0 0 0 0.04em rgba(255, 255, 255, 0.15);
}

/* Stack on narrow screens: label on top, then the two states. */
@media (max-width: 760px) {
  .font-features__head {
    display: none;
  }

  .font-features__row {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }

  .font-features__sample::before {
    content: attr(data-state);
    display: block;
    font-family: var(--font-ui);
    font-variant-ligatures: none;
    font-size: var(--text-xs);
    letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.5);
    margin-bottom: 0.15em;
  }
}

/* Stacked lines inside one sample (the figures module shows two). */
.font-features__line {
  display: block;
  white-space: nowrap;
  overflow: hidden;
}

/* ----------------------------------------------------------
   GLYPHS — explorer fetched into a lightbox. All four scripts
   are stacked in one scroll (no tabs); the right-hand panel
   shows the selected glyph's detail in place (no new layer).
   On mobile the detail stacks as a sticky header above the grid.
---------------------------------------------------------- */

/* Inline trigger (e.g. the glyph count on the start page) */
.glyphs-trigger {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-out);
}
.glyphs-trigger:hover { opacity: 0.6; }

/* Standalone button trigger (type tester, typeface statement). Same chip
   treatment as .examples__btn.is-active so it reads as part of the tester's
   control row rather than a foreign element. */
.glyphs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: #fff;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.glyphs-btn:hover { border-color: rgba(255, 255, 255, 0.4); }

/* Modal shell */
.glyphs-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: #000;
}
.glyphs-lightbox[hidden] { display: none; }
.glyphs-lightbox__content { height: 100%; }

/* Explorer container */
.glyph-explorer {
  --glyph-font: 'Exemplar', serif;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #000;
  color: #fff;
}

/* Top bar */
.glyph-explorer__bar {
  display: flex;
  height: 56px;
  flex: 0 0 56px;
  align-items: center;
  justify-content: space-between;
  align-items: middle;
  padding-inline: var(--container-gutter);
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
}
.glyph-explorer__close {
  flex: 0 0 auto;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  color: #fff;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity var(--duration-fast) var(--ease-out);
}
.glyph-explorer__close:hover { opacity: 1; }

/* Split body: scrolling grid + detail panel */
.glyph-explorer__body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr minmax(300px, 30%);
}

.glyph-explorer__scroll {
  overflow-y: auto;
  min-height: 0;
  padding-bottom: var(--space-4xl);
}

/* Per-script section */
.glyphs__script { padding-top: var(--space-2xl); }
.glyphs__script[dir="rtl"] .glyphs__script-head,
.glyphs__script[dir="rtl"] .glyphs__category-label { direction: ltr; text-align: left; }

.glyphs__script-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-md);
  padding-inline: var(--container-gutter);
  margin-bottom: var(--space-lg);
}
.glyphs__script-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.875rem, 3.33vw, 3rem); /* matches .statement__body */
  line-height: 1; /* mismatched inherited line-height vs. the count next to
    it was throwing off the flex baseline alignment between the two fonts */
  margin: 0;
}
.glyphs__script-count {
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 13px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.5);
}

.glyphs__category { padding-inline: var(--container-gutter); }
.glyphs__category + .glyphs__category { margin-top: var(--space-2xl); }
.glyphs__category-label {
  display: block;
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  margin-bottom: var(--space-md);
}

/* Cell grid */
.glyphs__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 1px;
  background: #000;
  //border: 1px solid rgba(255, 255, 255, 0.12);
}
.glyphs__cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  outline: 1px solid rgba(35, 35, 35);
  cursor: pointer;
  color: #fff;
  transition:
    background var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}
.glyphs__cell:hover,
.glyphs__cell:focus-visible { background: rgba(255, 255, 255, 0.12); outline: 1px solid rgba(35, 35, 35); }
.glyphs__cell.is-selected { background: #fff; color: #000; }
.glyphs__char {
  font-family: var(--glyph-font);
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  line-height: 1;
}

/* Detail panel */
.glyph-explorer__detail {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.15);
}
.glyph-explorer__stage {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  padding: var(--space-xl);
}
.glyph-explorer__char {
  font-family: var(--glyph-font);
  font-size: clamp(7rem, 20vw, 16rem);
  line-height: 1.5;
}
.glyph-explorer__meta {
  flex: 0 0 auto;
  margin: 0;
  padding: var(--space-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  font-family: var(--font-ui);
  font-variant-ligatures: none;
  font-size: 14px;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}
.glyph-explorer__meta-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
}
.glyph-explorer__meta dt { color: rgba(255, 255, 255, 0.5); font-size: 13px; }
.glyph-explorer__meta dd { margin: 0; }

/* Mobile: single column, detail becomes a sticky header above the grid */
@media (max-width: 768px) {
  .glyph-explorer__body {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    padding-bottom: var(--space-2xl);
  }
  .glyph-explorer__scroll { overflow: visible; }
  .glyph-explorer__detail {
    order: -1;
    flex: 0 0 auto;
    min-height: auto;
    position: sticky;
    top: 0;
    z-index: var(--z-raised);
    flex-direction: row;
    align-items: center;
    gap: var(--space-md);
    background: #000;
    border-left: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
    padding: var(--space-sm) var(--container-gutter);
  }
  .glyph-explorer__stage {
    flex: 0 1 auto;
    min-width: 7rem;
    padding: 0;
  }
  .glyph-explorer__char { font-size: 6rem; }
  .glyph-explorer__meta {
    flex: 1 1 auto;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-md);
    padding: 0;
    border-top: none;
    font-size: 11px;
  }
  .glyph-explorer__meta-row { flex-direction: column; gap: 0; }
  .glyph-explorer__meta-row:has([data-glyph-cat]) { display: none; }
  .glyph-explorer__meta dt { font-size: 11px; }
}
