@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/fraunces-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/fraunces-latin-400-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/inter-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/inter-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/inter-latin-400-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
  --bg: #faf7f0;
  --text: #1f1d1a;
  --accent: #b4552d;
  --muted: #72706b;
  --border: #dbd8d2;
  --surface: #fdfcf9;
  --accent-text: #b4552d;
  --accent-ui: #b4552d;
  --accent-fill: #b4552d;
  --on-accent: #faf7f0;
  --font-heading: "Fraunces", Iowan Old Style, Palatino, "Times New Roman", Georgia, serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --heading-weight: 600;
  --body-weight: 400;
  --bold-weight: 700;
  --font-size-base: clamp(1.0625rem, calc(1.0089rem + 0.2232vw), 1.1875rem);
  --line-height: 1.7;
  --radius: 6px;
  --space-unit: 1rem;
  --content-width: 42rem;
  --wide-width: 56rem;
}

/* Star Editor — shared base stylesheet.
   Every color and family here comes from the generated :root token block; this
   file must never contain a color literal or a font name (enforced by test). */

:root {
  --gutter: clamp(1rem, 4vw, 2rem);
  --block-gap: calc(var(--space-unit) * 1.75);
  --section-gap: calc(var(--space-unit) * 3);
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: var(--body-weight);
  font-size: var(--font-size-base);
  line-height: var(--line-height);
  /* A pasted URL or one very long word must wrap, not widen the page into a
     sideways scroll. `anywhere` also lets flex items (the header) shrink;
     `break-word` is the fallback for engines without it. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  line-height: 1.15;
  text-wrap: balance;
}

p,
ul,
ol,
figure,
blockquote,
pre,
hr {
  margin: 0;
}

img,
video,
iframe {
  max-width: 100%;
}

img {
  height: auto;
  border: 0;
}

strong,
b {
  font-weight: var(--bold-weight);
}

a {
  color: var(--accent-text);
  text-underline-offset: 0.18em;
}

::selection {
  background: var(--accent-fill);
  color: var(--on-accent);
}

/* No border-radius here: it would round the focused ELEMENT, not the ring —
   each element's own radius already shapes the outline. */
:focus-visible {
  outline: 3px solid var(--accent-ui);
  outline-offset: 2px;
}

/* --- skip link ---------------------------------------------------------- */

/* Clipped rather than moved off to one side: an off-screen link placed with a
   physical offset is a viewport-wide horizontal overflow under dir="rtl"
   (measured: documentElement.scrollWidth 1536 at a 768 px viewport). */
.skip-link {
  position: absolute;
  top: var(--gutter);
  inset-inline-start: var(--gutter);
  z-index: 100;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  padding: 0.6em 1em;
  border-radius: var(--radius);
  background: var(--accent-fill);
  color: var(--on-accent);
  font-weight: var(--bold-weight);
  text-decoration: none;
}

.skip-link:focus {
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
}

/* --- header and nav ----------------------------------------------------- */

/* The gutter is inside the box, so the header's content edges land exactly on
   the page grid's `wide` column at every viewport width. */
.site-header,
.site-footer {
  width: 100%;
  max-width: calc(var(--wide-width) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(var(--space-unit) * 0.5) var(--space-unit);
  padding-block: calc(var(--space-unit) * 1.5);
}

.site-name {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: 1.125rem;
  color: var(--text);
  text-decoration: none;
}

.site-name-emoji {
  margin-right: 0.35em;
}

.nav-menu {
  line-height: 1;
}

.nav-toggle {
  display: inline-block;
  padding: 0.35em 0.7em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 0.9375rem;
  cursor: pointer;
  list-style: none;
}

.nav-toggle::-webkit-details-marker {
  display: none;
}

/* The link list is a SIBLING of <details>, not a child: only that shape can be
   forced visible again at wide viewports with CSS alone, because engines hide a
   closed <details>'s own content in their shadow tree. */
.nav-list {
  display: none;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-menu[open] + .nav-list {
  display: flex;
  flex-direction: column;
  gap: calc(var(--space-unit) * 0.5);
  padding-block: var(--space-unit);
}

.nav-link,
.footer-link {
  color: var(--muted);
  text-decoration: none;
}

.nav-link:hover,
.nav-link:focus-visible,
.footer-link:hover,
.footer-link:focus-visible {
  color: var(--accent-text);
  text-decoration: underline;
}

.nav-link[aria-current="page"] {
  color: var(--text);
}

@media (min-width: 640px) {
  .nav-menu {
    display: none;
  }

  .nav-menu[open] + .nav-list,
  .nav-list {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: calc(var(--space-unit) * 1.25);
    padding-block: 0;
  }
}

/* --- page grid ---------------------------------------------------------- */

.page {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, calc((var(--wide-width) - var(--content-width)) / 2))
    [content-start] min(100% - var(--gutter) * 2, var(--content-width)) [content-end]
    minmax(0, calc((var(--wide-width) - var(--content-width)) / 2)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
  padding-block: var(--space-unit) var(--section-gap);
}

.page > * {
  grid-column: content;
  min-width: 0;
}

.page > * + * {
  margin-top: var(--block-gap);
}

.se-gallery,
.se-image--full {
  grid-column: wide;
}

/* --- blocks ------------------------------------------------------------- */

.se-h1 {
  font-size: clamp(2rem, 1.35rem + 3.2vw, 3rem);
}

.se-h2 {
  font-size: clamp(1.4rem, 1.15rem + 1.2vw, 1.75rem);
}

.page > .se-h1 + *,
.page > .se-h2 + * {
  margin-top: var(--space-unit);
}

.page > * + .se-h2 {
  margin-top: var(--section-gap);
}

.se-text > * + * {
  margin-top: 1em;
}

.se-text ul,
.se-text ol {
  padding-inline-start: 1.4em;
}

.se-text li + li {
  margin-top: 0.35em;
}

.se-image img {
  display: block;
  width: 100%;
  border-radius: var(--radius);
}

.se-image--medium {
  margin-inline: auto;
}

.se-caption,
.se-gallery-caption {
  margin-top: calc(var(--space-unit) * 0.5);
  color: var(--muted);
  font-size: 0.875em;
  line-height: 1.5;
}

.se-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--space-unit) * 0.5);
}

@media (min-width: 640px) {
  .se-gallery {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-unit);
  }
}

.se-gallery-item {
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  background: var(--surface);
}

.se-gallery-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.se-button {
  line-height: 1;
}

.button {
  display: inline-block;
  padding: 0.75em 1.35em;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent-fill);
  color: var(--on-accent);
  font-family: inherit;
  font-size: 1rem;
  font-weight: var(--bold-weight);
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.button:hover,
.button:focus-visible {
  text-decoration: underline;
}

.se-video {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  background: var(--surface);
}

.se-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.se-video-facade {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: cover;
  color: var(--text);
  font-weight: var(--bold-weight);
  text-decoration: none;
}

.se-video-facade::before {
  content: "";
  width: 0;
  height: 0;
  margin-right: 0.7em;
  border-style: solid;
  border-width: 0.6em 0 0.6em 1.05em;
  border-color: transparent transparent transparent var(--accent-fill);
}

.se-quote {
  padding-inline-start: var(--space-unit);
  border-inline-start: 3px solid var(--accent-ui);
}

.se-quote-text {
  font-size: 1.125em;
}

.se-quote-attribution {
  margin-top: calc(var(--space-unit) * 0.5);
  color: var(--muted);
  font-size: 0.9375em;
}

.se-quote-attribution::before {
  content: "\2014\00a0";
}

.se-divider {
  height: 0;
  margin-block: var(--section-gap);
  border: 0;
  border-top: 1px solid var(--border);
}

/* --- footer ------------------------------------------------------------- */

.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space-unit) * 0.5) var(--space-unit);
  padding-block: var(--section-gap) calc(var(--space-unit) * 2);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.875rem;
}

.footer-made-with {
  margin-inline-start: auto;
}

/* --- lightbox ----------------------------------------------------------- */

.se-lightbox {
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
}

.se-lightbox::backdrop {
  background: var(--surface);
  opacity: 0.98;
}

.se-lightbox[open] {
  animation: se-lightbox-in 160ms ease-out;
}

@keyframes se-lightbox-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.se-lightbox-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: var(--gutter);
  gap: var(--space-unit);
}

.se-lightbox-image {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--radius);
}

.se-lightbox-caption {
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: center;
}

.se-lightbox-button {
  position: absolute;
  padding: 0.5em 0.75em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.se-lightbox-close {
  top: var(--gutter);
  inset-inline-end: var(--gutter);
}

/* Logical, not left/right: previous and next follow the reading direction, so
   under dir="rtl" the arrows swap sides with the pictures they step through. */
.se-lightbox-prev {
  top: 50%;
  inset-inline-start: var(--gutter);
  transform: translateY(-50%);
}

.se-lightbox-next {
  top: 50%;
  inset-inline-end: var(--gutter);
  transform: translateY(-50%);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Paper — a beautifully typeset article.

   Typography is the design: one flush-left column, a serif display face over a
   quiet sans, hairlines used sparingly, and a single recurring mark — the short
   accent block — under the page title, beside quotes and on the current nav item.

   Constraints this file works under:
   - tokens only: no color literals, no family names (StaticCSSTests reads the
     comments too);
   - the heading family ships exactly two faces for this theme — upright at
     --heading-weight and italic at 400 — so every italic use of --font-heading
     pins font-weight: 400, or the browser fakes a bold on top of it;
   - the body family ships 400, 400 italic and --bold-weight, nothing between;
   - vertical space is counted in body lines (--line), so every block sits on
     one rhythm whatever the viewport does to the base size;
   - color-mix() is decoration only (rules, shadows, underline tints). Text
     always takes a contrast-checked token. */

:root {
  --leading: 1.65;
  --line: calc(var(--font-size-base) * var(--leading));
  --block-gap: calc(var(--line) * 1.1);
  --figure-gap: calc(var(--line) * 1.75);
  --section-gap: calc(var(--line) * 2.25);
  --paper-radius: calc(var(--radius) * 0.5);
  --header-pad: 1.25rem;
  --edge: var(--border);
}

@media (min-width: 640px) {
  :root {
    --leading: var(--line-height);
    --section-gap: calc(var(--line) * 2.75);
    --header-pad: 1.75rem;
  }
}

/* base draws the masthead and the wide media band from --wide-width. Paper
   ramps that width with the window rather than switching it at a breakpoint,
   so nothing lurches: the band opens only once the window has room outside the
   text column, then grows while keeping 6rem of air on each side, and stops at
   the theme's maximum. The maximum is copied into its own property first
   because a custom property may not reference itself, and the ramp is declared
   on <body> so the header, footer and page grid inherit it.
   54rem = --content-width + that 12rem of air: the width where the band starts
   to exist, and therefore the one breakpoint this theme treats as "wide". */
:root {
  --paper-wide-cap: var(--wide-width);
}

/* The column is a flex child so a short page (the 404, a one-paragraph About)
   still pushes the footer to the bottom of the window. */
body {
  --wide-width: min(var(--paper-wide-cap), max(var(--content-width), 100vw - 12rem));
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  line-height: var(--leading);
  font-kerning: normal;
}

::selection {
  background: var(--accent-fill);
  color: var(--on-accent);
}

@supports (color: color-mix(in srgb, currentColor 50%, transparent)) {
  :root {
    --edge: color-mix(in srgb, var(--text) 11%, transparent);
  }

  ::selection {
    background: color-mix(in srgb, var(--accent) 22%, transparent);
    color: var(--text);
  }

  .button::selection {
    background: var(--on-accent);
    color: var(--accent-fill);
  }
}

/* No border-radius here: that would reshape the focused element itself, not
   the ring. Each element's own radius shapes it. */
:focus-visible {
  outline: 2px solid var(--accent-ui);
  outline-offset: 3px;
}

/* --- masthead ------------------------------------------------------------ */

/* Rules are drawn as backgrounds, inset by the gutter, so they end exactly on
   the wide column like the images do; a border would run into the gutters. */
.site-header {
  position: relative;
  row-gap: 0;
  padding-block: var(--header-pad);
  background: linear-gradient(var(--border), var(--border)) center bottom / calc(100% - var(--gutter) * 2) 1px no-repeat;
}

/* Room is kept for the menu toggle, which is taken out of flow so that a long
   site name wraps beside it instead of knocking it onto a second row. */
.site-name {
  max-width: calc(100% - 6rem);
  font-size: 1.0625rem;
  line-height: 1.3;
  letter-spacing: -0.005em;
  text-wrap: balance;
  transition: color 160ms ease;
}

.site-header:not(:has(nav)) .site-name {
  max-width: none;
}

.site-name:hover {
  color: var(--accent-text);
}

.site-header nav {
  flex: 1 0 100%;
}

/* 0.6875rem = half of what the 2.75rem tap target stands taller than the site
   name's first line, so the two share a centre line. The toggle's own padding
   is pulled back out of the gutter so its icon still ends on the column edge
   while the focus ring sits evenly around it. */
.nav-menu {
  position: absolute;
  top: calc(var(--header-pad) - 0.6875rem);
  inset-inline-end: calc(var(--gutter) - 0.5rem);
}

.nav-toggle {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0 0.5rem;
  border: 0;
  border-radius: var(--paper-radius);
  color: var(--text);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.nav-toggle::after {
  content: "";
  width: 1.125rem;
  height: 0.4375rem;
  border-block: 1.5px solid currentColor;
  transition: height 160ms ease, transform 160ms ease;
}

/* Open, the two bars cross: a single dash does not say "close". The second
   stroke can only be a second pseudo-element, so it is laid over the icon —
   which sits at the end of the flex row, inside the toggle's own padding. */
.nav-menu[open] .nav-toggle::after {
  height: 0;
  border-bottom-width: 0;
  transform: rotate(45deg);
}

.nav-menu[open] .nav-toggle::before {
  content: "";
  position: absolute;
  inset-inline-end: 0.5rem;
  top: calc(50% - 0.75px);
  width: 1.125rem;
  height: 1.5px;
  background: currentColor;
  transform: rotate(-45deg);
}

.nav-menu[open] + .nav-list {
  gap: 0;
  padding-block: 0.875rem 0;
}

.nav-link {
  display: block;
  padding-block: 0.6875rem;
  color: var(--text);
  font-size: 1.0625rem;
  line-height: 1.3;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: color 160ms ease;
}

.nav-link:hover,
.nav-link:focus-visible {
  color: var(--accent-text);
  text-decoration: none;
}

.nav-link[aria-current="page"]::before {
  content: "";
  display: inline-block;
  width: 0.875rem;
  height: 0.1875rem;
  margin-inline-end: 0.625rem;
  vertical-align: 0.28em;
  background: var(--accent-ui);
}

@media (min-width: 640px) {
  .site-header {
    column-gap: 2.5rem;
  }

  .site-name {
    max-width: none;
    font-size: 1.125rem;
  }

  .site-header nav {
    flex: 0 1 auto;
  }

  .nav-menu[open] + .nav-list,
  .nav-list {
    gap: 0.25rem 1.75rem;
    padding-block: 0;
  }

  .nav-link {
    display: inline-block;
    padding-block: 0.375rem;
    color: var(--muted);
    font-size: 0.9375rem;
  }

  .nav-link:hover,
  .nav-link:focus-visible {
    color: var(--text);
  }

  .nav-link[aria-current="page"] {
    background: linear-gradient(var(--accent-ui), var(--accent-ui)) left bottom / 1.125rem 2px no-repeat;
    color: var(--text);
  }

  .nav-link[aria-current="page"]::before {
    content: none;
  }
}

/* --- page rhythm --------------------------------------------------------- */

.page {
  flex: 1 0 auto;
  align-content: start;
  padding-block: clamp(2.75rem, 1.75rem + 5vw, 5.5rem) calc(var(--line) * 3.5);
}

/* A page with no picture on it — the not-found page, a one-line note — is
   composed in the window instead of being pinned to the top with the footer
   marooned below it. The column never shrinks below its content (flex-shrink
   is 0 above), so centring can never push the first line out of reach. */
.page:not(:has(.se-image, .se-gallery, .se-video)) {
  align-content: center;
}

/* Order matters below: every selector weighs the same, the later one wins. */
.page > .se-text + .se-text {
  margin-top: calc(var(--line) * 0.7);
}

.page > * + :is(.se-image, .se-gallery, .se-video, .se-quote),
.page > :is(.se-image, .se-gallery, .se-video, .se-quote) + * {
  margin-top: var(--figure-gap);
}

.page > * + .se-button {
  margin-top: calc(var(--line) * 1.5);
}

.page > .se-button + .se-button {
  margin-top: calc(var(--line) * 0.25);
}

.page > * + .se-h2 {
  margin-top: var(--section-gap);
}

.page > .se-h1 + * {
  margin-top: calc(var(--line) * 1.25);
}

.page > .se-h2 + * {
  margin-top: calc(var(--line) * 0.6);
}

.page > .se-h2 + :is(.se-image, .se-gallery, .se-video, .se-quote) {
  margin-top: var(--line);
}

.page > * + .se-divider,
.page > .se-divider + * {
  margin-top: var(--section-gap);
}

/* --- headings ------------------------------------------------------------ */

/* Display type grows only while its measure grows. The first clamp tracks the
   text column and levels off as that column reaches its full 42rem; the second
   picks up at 54rem, where the wide band starts widening the title again, and
   tops out at 68rem where the band reaches its maximum. Between the two the
   title holds still. Set as one clamp to 60px it gained a LINE as the window
   got wider, because it kept growing against a frozen measure.
   A long title may run past the measure to the edge the wide pictures use;
   below 54rem `wide-end` and `content-end` are the same grid line, so that
   needs no media query of its own. */
.se-h1 {
  grid-column: content-start / wide-end;
  font-size: clamp(2.25rem, 1.65rem + 3vw, 3.125rem);
  line-height: 1.08;
  letter-spacing: -0.022em;
}

@media (min-width: 54rem) {
  .se-h1 {
    font-size: clamp(3.125rem, 0.71rem + 4.464vw, 3.75rem);
  }
}

/* The signature: a short accent block hung under the oversized title. */
.se-h1::after {
  content: "";
  display: block;
  width: clamp(3rem, 2.4rem + 2.5vw, 4.5rem);
  height: clamp(0.25rem, 0.2rem + 0.25vw, 0.375rem);
  margin-top: 0.5em;
  background: var(--accent-ui);
}

.se-h2 {
  font-size: clamp(1.5rem, 1.3rem + 1vw, 1.9375rem);
  line-height: 1.2;
  letter-spacing: -0.012em;
}

/* --- text ---------------------------------------------------------------- */

.se-text > * + * {
  margin-top: calc(var(--line) * 0.7);
}

.se-text p,
.se-text li {
  text-wrap: pretty;
}

/* A phone measure runs about 31 characters, where a deep rag is the difference
   between an even page and a ragged one; the renderer always writes lang on
   <html>, so the dictionary is picked for us. Wider than this the measure
   holds its own and hyphens would only add noise.
   The limits keep short words whole and stop a ladder of hyphens; WebKit
   understands only its own prefixed pair, Blink only the standard property, so
   both are set. */
@media (max-width: 639.98px) {
  .se-text p,
  .se-text li {
    -webkit-hyphens: auto;
    hyphens: auto;
    -webkit-hyphenate-limit-before: 4;
    -webkit-hyphenate-limit-after: 3;
    -webkit-hyphenate-limit-lines: 2;
    hyphenate-limit-chars: 7 4 3;
    hyphenate-limit-lines: 2;
  }
}

/* The lede: the opening paragraph of the page, wherever the first text block
   sits, but never one that only turns up after a section heading. The brief
   pins the size at 1.05em, which on its own is a difference nobody sees, so
   the paragraph is also set tighter and closer than body copy — a standfirst
   reads as a denser block of type, not as slightly bigger text. */
.page > .se-text:not(.se-text ~ .se-text):not(.se-h2 ~ .se-text) > p:first-child {
  font-size: 1.05em;
  line-height: 1.45;
  letter-spacing: -0.008em;
}

.page > .se-text:not(.se-text ~ .se-text):not(.se-h2 ~ .se-text) > p:first-child + * {
  margin-top: var(--line);
}

.se-text a,
.se-caption a {
  text-decoration-line: underline;
  text-decoration-thickness: max(1px, 0.06em);
  text-underline-offset: 0.22em;
  text-decoration-color: var(--accent-ui);
  text-decoration-color: color-mix(in srgb, var(--accent-text) 45%, transparent);
  transition: text-decoration-color 160ms ease;
}

.se-text a:hover,
.se-caption a:hover {
  text-decoration-color: currentColor;
}

.se-text ul {
  padding-inline-start: 1.3em;
}

/* Wider, so a two-digit numeral still hangs inside a phone's gutter. */
.se-text ol {
  padding-inline-start: 1.6em;
}

.se-text li {
  padding-inline-start: 0.2em;
}

.se-text li + li {
  margin-top: calc(var(--line) * 0.3);
}

.se-text ul > li::marker {
  color: var(--accent-ui);
}

.se-text ol > li::marker {
  color: var(--accent-text);
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-variant-numeric: tabular-nums;
}

/* --- figures ------------------------------------------------------------- */

.se-image img {
  border-radius: var(--paper-radius);
  outline: 1px solid var(--edge);
  outline-offset: -1px;
}

/* A portrait picture is held to a screenful and keeps its proportions rather
   than being cropped. The figure shrinks to the picture — base centres it,
   which is the one place this theme would break its flush-left column — and
   the caption is kept from widening it again, so picture, caption and text all
   start on the same line. A very small picture still gets a caption wide
   enough to read. */
.se-image--medium {
  justify-self: start;
  min-width: min(100%, 18rem);
  margin-inline: 0;
}

.se-image--medium img {
  width: auto;
  max-height: min(80vh, 38rem);
}

.se-image--medium .se-caption {
  width: 0;
  min-width: 100%;
}

.se-caption {
  margin-top: 0.75rem;
  font-size: 0.8125em;
  line-height: 1.5;
  text-wrap: balance;
}

/* A caption is prose, so it keeps the text measure and the text column's left
   edge however wide the picture above it runs. The wide band is symmetric
   about the text column, so centring the caption inside it lands it exactly on
   that edge. */
.se-image--full .se-caption {
  max-width: var(--content-width);
  margin-inline: auto;
}

/* Only on a phone, where the column IS the window, does a full image bleed to
   the screen edges; there the caption rebuilds the text column under it. From
   640px up the picture takes the wide band instead — which starts out as the
   text column and opens with the window — because an edge-to-edge photograph
   beside a 42rem measure belongs to a louder theme than this one. */
@media (max-width: 639.98px) {
  .se-image--full {
    grid-column: full;
  }

  .se-image--full img {
    border-radius: 0;
    outline: 0;
  }

  .se-image--full .se-caption {
    width: min(100% - var(--gutter) * 2, var(--content-width));
  }
}

/* --- gallery ------------------------------------------------------------- */

.se-gallery {
  gap: 0.5rem;
}

.se-gallery-item {
  position: relative;
  border-radius: var(--paper-radius);
  cursor: zoom-in;
}

.se-gallery-item::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--edge);
  pointer-events: none;
}

/* No holes in the grid: an odd set leads with one wide picture on a phone… */
@media (max-width: 639.98px) {
  .se-gallery-item:first-child:nth-last-child(odd) {
    grid-column: span 2;
    aspect-ratio: 3 / 2;
  }
}

/* …and on a wide screen only the LAST row is ever re-dealt, so adding a
   picture re-sets one row instead of restyling the whole block. Twelve columns
   is what lets a row hold three, four or two: full rows stay 3-up squares, a
   row left two short is dealt as four narrower squares, and a row left one
   short as two 3:2 pictures. The renderer knows this deal (`GalleryGrid.paper`)
   and writes each thumbnail's `sizes` from it, so a wider cell is served a
   wider variant instead of an upscaled one — keep the two in step. */
@media (min-width: 640px) {
  .se-gallery {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 0.75rem;
  }

  .se-gallery-item {
    grid-column: span 4;
  }

  .se-gallery-item:nth-child(3n + 1):nth-last-child(2),
  .se-gallery-item:nth-child(3n + 2):nth-last-child(1) {
    grid-column: span 6;
    aspect-ratio: 3 / 2;
  }

  .se-gallery-item:nth-child(3n + 1):nth-last-child(4),
  .se-gallery-item:nth-child(3n + 2):nth-last-child(3),
  .se-gallery-item:nth-child(3n):nth-last-child(2),
  .se-gallery-item:nth-child(3n + 1):nth-last-child(1) {
    grid-column: span 3;
  }

  /* The one count with no row to share: a single picture takes the whole band
     rather than leaving three quarters of a row empty. Matched on the count
     the renderer writes, and listed last, so it outranks the 3n+1 rule above —
     which is what the plain :only-child it replaces could never do. */
  .se-gallery[data-count="1"] .se-gallery-item {
    grid-column: 1 / -1;
    aspect-ratio: 3 / 2;
  }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .se-gallery-item img {
    transition: transform 600ms cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  .se-gallery-item:hover img {
    transform: scale(1.035);
  }
}

/* --- video --------------------------------------------------------------- */

/* Nothing is fetched before the click, so there is no poster frame: the facade
   is set as a title card instead — a mat, a hairline frame, a tinted panel, a
   disc and one line of italic. Disc, label and provider are all placed from
   the middle of the frame, spaced so the three read as one centred group at
   any card size. The card takes the wide band with the gallery and the full
   image, so all three media blocks share one pair of edges; below 54rem that
   band is the text column. */
.se-video {
  grid-column: wide;
  isolation: isolate;
  border-radius: var(--paper-radius);
  background: var(--surface);
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
}

.se-video-facade {
  position: relative;
  padding-top: 3.25rem;
  border-radius: inherit;
  box-shadow:
    inset 0 0 0 1px var(--edge),
    inset 0 0 0 0.5rem var(--surface),
    inset 0 0 0 calc(0.5rem + 1px) var(--edge);
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 400;
  font-size: 1.1875rem;
  line-height: 1.3;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}

.se-video-facade::before {
  position: absolute;
  top: calc(50% - 1.125rem);
  left: 50%;
  width: 2.75rem;
  height: 2.75rem;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: var(--accent-fill);
  transform: translate(-50%, -50%);
}

.se-video-facade::after {
  content: "";
  position: absolute;
  top: calc(50% - 1.125rem);
  left: 50%;
  width: 0.75rem;
  height: 0.875rem;
  background: var(--on-accent);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  transform: translate(-36%, -50%);
}

.se-video-facade:hover,
.se-video-facade:focus-visible {
  text-decoration-line: underline;
}

/* The frame clips its children, so the ring is drawn inside it. */
.se-video-facade:focus-visible {
  outline-offset: -0.5rem;
}

/* The three lines are hung off the middle so the group is balanced whatever
   the card's height: the disc ends on the middle line, the title sits below it
   (the facade's top padding is twice its offset, because flex centring splits
   the padding), and the provider closes the group the same distance below the
   title. */
@media (min-width: 640px) {
  .se-video-facade {
    box-shadow:
      inset 0 0 0 1px var(--edge),
      inset 0 0 0 0.75rem var(--surface),
      inset 0 0 0 calc(0.75rem + 1px) var(--edge);
    font-size: 1.375rem;
  }

  .se-video-facade::before {
    top: calc(50% - 2rem);
    width: 4rem;
    height: 4rem;
  }

  .se-video-facade::after {
    top: calc(50% - 2rem);
    width: 1.0625rem;
    height: 1.25rem;
  }

  .se-video-facade:focus-visible {
    outline-offset: -0.75rem;
  }

  /* Where the player comes from, said before the click. It is painted BEHIND
     the frame's children (z-index -1 in the isolated context above) so the
     swapped-in iframe covers it; a phone-sized card has no room for it. */
  .se-video::after {
    content: attr(data-provider);
    position: absolute;
    z-index: -1;
    top: calc(50% + 3.25rem);
    inset-inline: 0;
    color: var(--muted);
    font-size: 0.6875rem;
    line-height: 1;
    letter-spacing: 0.16em;
    text-align: center;
    text-indent: 0.16em;
    text-transform: uppercase;
  }
}

/* --- quote --------------------------------------------------------------- */

.se-quote {
  padding-inline-start: 1.25rem;
  border-inline-start: 3px solid var(--accent-ui);
}

.se-quote-text {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.3125rem, 1.2rem + 0.55vw, 1.5625rem);
  line-height: 1.45;
  letter-spacing: -0.005em;
  text-wrap: pretty;
}

.se-quote-attribution {
  margin-top: calc(var(--line) * 0.5);
  font-size: 0.8125em;
  letter-spacing: 0.01em;
}

/* With margin to spare, the rule hangs outside the column and the quotation
   itself stays on the text edge. */
@media (min-width: 54rem) {
  .se-quote {
    margin-inline-start: calc(-1.75rem - 3px);
    padding-inline-start: 1.75rem;
  }
}

/* --- buttons ------------------------------------------------------------- */

/* Quiet by default: a text-weight link with a chevron. It carries a rest-state
   rule in full accent, where a sentence link's is tinted back to 45%, so the
   action still out-signals the prose around it — a button with nothing under
   it at rest read as LESS clickable than an ordinary link. Hover doubles the
   rule and takes the text colour. The chevron is out of flow, in room the
   padding keeps for it, because an in-flow one can wrap onto a line of its own
   under a long label. */
.button {
  position: relative;
  padding-block: 0.75rem;
  padding-inline: 0 1.125em;
  border-radius: 0;
  background: none;
  color: var(--accent-text);
  font-weight: var(--body-weight);
  line-height: 1.3;
  text-align: start;
  text-decoration-line: underline;
  text-decoration-color: var(--accent-ui);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.28em;
  transition: text-decoration-color 160ms ease;
}

.button:hover,
.button:focus-visible {
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}

.button::after {
  content: "";
  position: absolute;
  top: 50%;
  inset-inline-end: 0.2em;
  width: 0.4375em;
  height: 0.4375em;
  margin-top: -0.2em;
  border-block-start: 1.5px solid currentColor;
  border-inline-end: 1.5px solid currentColor;
  transform: rotate(45deg);
}

/* The chevron is drawn from two logical borders and then turned; mirroring the
   box does not mirror the turn, so right-to-left needs the opposite one. */
.button:dir(rtl)::after {
  transform: rotate(-45deg);
}

/* The pill is kept for the primary action — the first button on the page. Its
   shape is the signal, so it carries no rule at all. */
.page > .se-button:not(.se-button ~ .se-button) .button {
  padding-block: 0.75em;
  padding-inline: 1.625em 2.875em;
  border-radius: 1.75em;
  background: var(--accent-fill);
  color: var(--on-accent);
  letter-spacing: 0.005em;
  text-decoration-line: none;
  transition: filter 160ms ease;
}

.page > .se-button:not(.se-button ~ .se-button) .button:hover,
.page > .se-button:not(.se-button ~ .se-button) .button:focus-visible {
  text-decoration-line: none;
  filter: brightness(0.94);
}

.page > .se-button:not(.se-button ~ .se-button) .button::after {
  inset-inline-end: 1.5em;
}

.page > .se-button:not(.se-button ~ .se-button) .button:active {
  filter: brightness(0.88);
}

/* --- divider ------------------------------------------------------------- */

/* Hung on the text column's left edge, like the title's accent block and the
   quote's rule: a short mark centred inside a strictly flush-left page reads
   as an orphan. */
.se-divider {
  width: 4.5rem;
  margin-block: 0;
  margin-inline: 0;
  border-top-color: var(--muted);
}

/* --- colophon ------------------------------------------------------------ */

.site-footer {
  align-items: baseline;
  gap: 0 1.5rem;
  padding-block: calc(var(--line) * 1.1) calc(var(--line) * 1.75);
  border-top: 0;
  background: linear-gradient(var(--border), var(--border)) center top / calc(100% - var(--gutter) * 2) 1px no-repeat;
  font-size: 0.8125rem;
  line-height: 1.4;
}

.footer-link {
  padding-block: 0.8125rem;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
  transition: color 160ms ease;
}

.footer-link:hover,
.footer-link:focus-visible {
  color: var(--text);
}

.footer-made-with {
  flex-basis: 100%;
  margin-top: 0.75rem;
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 400;
  font-size: 0.9375rem;
}

@media (min-width: 640px) {
  .footer-made-with {
    flex-basis: auto;
    margin-top: 0;
  }
}

/* --- lightbox ------------------------------------------------------------ */

/* A clean sheet behind the picture: any see-through and the page's own text
   ghosts up behind the caption. */
.se-lightbox::backdrop {
  background: var(--bg);
  opacity: 1;
}

/* On a phone the picture, its caption and the arrows are ONE centred group:
   the dialog wraps them onto two flex lines, so the arrows always sit the same
   short distance under the caption. Pinned to the foot of the window instead,
   they were stranded half a screen below a small picture. The close button is
   out of flow, so it keeps its corner.
   The script closes on a click whose target is the dialog itself: letting
   clicks fall through the figure's empty space is what makes a tap beside the
   picture close it. */
.se-lightbox[open] {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  gap: 1.75rem 1rem;
}

.se-lightbox-figure {
  flex: 0 0 100%;
  height: auto;
  gap: 1rem;
  padding-block: 0;
  pointer-events: none;
}

.se-lightbox-image,
.se-lightbox-caption {
  pointer-events: auto;
}

/* Leaves room for the caption, the arrows and the close button's corner. */
.se-lightbox-image {
  max-height: calc(100vh - 18rem);
  max-height: calc(100dvh - 18rem);
  border-radius: var(--paper-radius);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--edge);
  box-shadow:
    0 0 0 1px var(--edge),
    0 1.5rem 3.5rem -1rem color-mix(in srgb, var(--text) 28%, transparent);
}

.se-lightbox-caption {
  max-width: 34rem;
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.45;
  text-wrap: balance;
}

.se-lightbox-button {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0 0 0.15em;
  border-color: var(--border);
  border-radius: 50%;
  background: var(--surface);
  font-size: 1.375rem;
  transition: border-color 160ms ease, color 160ms ease;
}

.se-lightbox-button:hover {
  border-color: var(--accent-ui);
  color: var(--accent-text);
}

/* In the flow of that group, side by side under the caption and inside thumb
   reach, instead of covering the picture's edges. */
.se-lightbox-prev,
.se-lightbox-next {
  position: static;
  transform: none;
}

/* With room to spare the picture goes back to the middle of the window and the
   arrows to its sides. */
@media (min-width: 768px) {
  .se-lightbox[open] {
    display: block;
  }

  .se-lightbox-figure {
    height: 100%;
    padding: 3rem 6rem;
  }

  .se-lightbox-image {
    max-height: calc(100vh - 10rem);
    max-height: calc(100dvh - 10rem);
  }

  .se-lightbox-prev,
  .se-lightbox-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }

  .se-lightbox-prev {
    left: 1.5rem;
  }

  .se-lightbox-next {
    right: 1.5rem;
  }
}

/* --- motion -------------------------------------------------------------- */

/* Base shortens transitions for reduced motion; the movements themselves are
   only declared for people who have not asked for less. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .button::after,
  .se-video-facade::before {
    transition: transform 200ms ease;
  }

  .button:hover::after {
    transform: translateX(0.1875em) rotate(45deg);
  }

  .button:dir(rtl):hover::after {
    transform: translateX(-0.1875em) rotate(-45deg);
  }

  .se-video-facade:hover::before {
    transform: translate(-50%, -50%) scale(1.06);
  }
}

/* --- print --------------------------------------------------------------- */

@media print {
  .nav-menu,
  .nav-list,
  .site-footer,
  .se-lightbox {
    display: none;
  }

  .se-h2,
  .se-quote,
  .se-image {
    break-inside: avoid;
  }

  .se-h2 {
    break-after: avoid;
  }

  /* A video cannot print, but dropping the block would lose part of the
     article without a trace. The title card collapses to its own line and
     says where the film lives. */
  .se-video {
    aspect-ratio: auto;
    background: none;
  }

  .se-video::after {
    display: none;
  }

  .se-video-facade {
    display: block;
    padding: 0;
    box-shadow: none;
    font-size: 1rem;
  }

  .se-video-facade::before {
    display: none;
  }

  .se-video-facade::after {
    content: " — " attr(href);
    position: static;
    width: auto;
    height: auto;
    background: none;
    clip-path: none;
    font-family: var(--font-body);
    font-style: normal;
    font-size: 0.8125rem;
    transform: none;
  }
}
