/* layout.css — grid/flex and measure only (SF-3 §VI): no colour, face or size
 * literal; lengths come from the --sk-* scale tokens. */

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

/* The leaf keeps one width and position on every page: the scrollbar's space is always
 * reserved, so a page long enough to scroll is no narrower than a short one. */
html { scrollbar-gutter: stable; }

body {
  position: relative;
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--sk-leaf-margin);
}

/* The leaf fills the viewport's height on a short page, so it reads as a sheet. */
.sk-leaf {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: calc(var(--sk-measure) + 2 * var(--sk-leaf-padding-inline));
  padding: var(--sk-leaf-padding-block) var(--sk-leaf-padding-inline);
}
.sk-vine {
  position: absolute;
  inset: var(--sk-band-inset);
  pointer-events: none;
}
/* Each rose is centred where its two vines cross (band-inset + half the band in from
 * both edges) and sized from the band, so it stays inside the outer rule at every width. */
.sk-rose {
  position: absolute;
  width: var(--sk-rose-size);
  height: var(--sk-rose-size);
  pointer-events: none;
}
.sk-rose-tl { top: var(--sk-rose-centre); left: var(--sk-rose-centre); transform: translate(-50%, -50%); }
.sk-rose-tr { top: var(--sk-rose-centre); right: var(--sk-rose-centre); transform: translate(50%, -50%); }
.sk-rose-bl { bottom: var(--sk-rose-centre); left: var(--sk-rose-centre); transform: translate(-50%, 50%); }
.sk-rose-br { bottom: var(--sk-rose-centre); right: var(--sk-rose-centre); transform: translate(50%, 50%); }

/* The seal: upper right, above the navigation (a cell of the header grid). */
.sk-seal { grid-area: seal; justify-self: end; margin: 0; }
.sk-seal-mark { display: block; width: var(--sk-seal-size); height: var(--sk-seal-size); }

/* The rose between sections, centred above the next section's heading. */
.sk-prose + .sk-section::before, .sk-opening + .sk-section::before, .sk-section + .sk-section::before {
  display: block;
  width: var(--sk-divider-size);
  height: var(--sk-divider-size);
  margin: 0 auto var(--sk-divider-gap);
}
/* No rose between two sections that are both document lists (drafts, samples): they read as one
 * run of boxes (Cam, 2026-10-27). */
.sk-section:has(> .sk-doclist) + .sk-section:has(> .sk-doclist)::before { content: none; }
/* The medallion once, at the end of the page, centred between the end of the page's content and
 * the footer rule (Cam, 2026-10-25). The footer is a column that takes the leaf's spare height;
 * the medallion's auto margins split that space evenly above and below it, on top of an equal
 * fixed gap each side (the footer's top padding above, the rule's top margin below). */
.sk-footer {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-top: var(--sk-space-6);
}
.sk-medallion {
  display: block;
  flex: none;
  width: var(--sk-fleuron-size);
  height: var(--sk-fleuron-size);
  margin: auto;
}
.sk-medallion-mark { display: block; width: 100%; height: 100%; }

.sk-header, .sk-main, .sk-footer {
  width: 100%;
  max-width: var(--sk-measure);
}
/* Every page, Teaching included, uses this one text column (Cam's option A, 2026-10-23);
 * the narrower reading variant (--sk-measure-reading, kept in the scale) is not applied. */

/* The header is a grid whose arrangement is two tokens: --sk-header-areas / -columns on
 * a wide page, --sk-header-areas-mobile / -columns-mobile below the nav-collapse width.
 * Its cells are seal, name, nav (inline) and menu; moving one is a token edit. */
.sk-header {
  position: relative;
  display: grid;
  grid-template-columns: var(--sk-header-columns);
  grid-template-areas: var(--sk-header-areas);
  align-items: baseline;
  gap: var(--sk-space-2) var(--sk-space-4);
  padding-bottom: var(--sk-space-2);
  margin-bottom: var(--sk-header-gap);
}
.sk-sitename { grid-area: name; margin: 0; align-self: end; white-space: nowrap; }
/* On a wide page the nav has its own row under the name and seal, spread across the measure. */
.sk-nav-inline { grid-area: nav; }
.sk-nav-inline ul { justify-content: space-between; }
.sk-menu { grid-area: menu; display: none; }

/* Below the nav-collapse width (= --sk-nav-collapse; a media query cannot read a token):
 * the hamburger menu replaces the inline nav, and the site name is centred. */
@media (max-width: 55rem) {
  .sk-header {
    grid-template-columns: var(--sk-header-columns-mobile);
    grid-template-areas: var(--sk-header-areas-mobile);
    align-items: center;
  }
  .sk-sitename { text-align: center; white-space: normal; }
  .sk-seal, .sk-menu { justify-self: center; }
  .sk-seal-mark { width: var(--sk-seal-size-mobile); height: var(--sk-seal-size-mobile); }
  .sk-nav-inline { display: none; }
  .sk-menu { display: block; }
  /* A tighter phone header (Cam, 2026-10-26): seal and menu button scaled down together, closer rows. */
  .sk-header { row-gap: var(--sk-space-1); }
  .sk-leaf { padding-top: var(--sk-leaf-padding-top-mobile); }
}

.sk-menu-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--sk-touch-target);
  height: var(--sk-touch-target);
  cursor: pointer;
  list-style: none;
}
.sk-menu-button::-webkit-details-marker { display: none; }
@media (max-width: 55rem) {
  .sk-menu-button { width: var(--sk-menu-button-mobile); height: var(--sk-menu-button-mobile); }
  .sk-menu-icon { width: var(--sk-menu-icon-w-mobile); height: var(--sk-menu-icon-h-mobile); }
}
.sk-menu-icon { position: relative; display: block; width: var(--sk-menu-icon-w); height: var(--sk-menu-icon-h); }
.sk-menu-icon::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); }
/* The open list drops below the header, full width, one 44 px row per page. */
.sk-nav-menu {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 2;
  padding: var(--sk-space-1) 0;
}
.sk-nav-menu ul { flex-direction: column; gap: 0; }
.sk-nav-menu a { display: flex; padding: 0 var(--sk-space-3); }
.sk-nav-menu li + li { margin: 0 var(--sk-space-3); }
.sk-nav-menu li:first-child { margin: 0 var(--sk-space-3); }
.sk-nav-menu li a { padding: 0; }
.sk-visually-hidden {
  position: absolute;
  width: var(--sk-hairline);
  height: var(--sk-hairline);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sk-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sk-space-1) var(--sk-nav-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}
.sk-nav a, .sk-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--sk-touch-target);
}

/* The main column takes its content's height (the footer takes the spare height), and the last
 * block's trailing margin is dropped so the gap above the medallion starts at the content itself. */
.sk-main { flex: none; }
.sk-main > :last-child, .sk-main > :last-child > :last-child, .sk-main > :last-child > :last-child > :last-child { margin-bottom: 0; }
.sk-main::after { content: ''; display: block; clear: both; }

/* The portrait: beside the title and bio on a wide page (floated right), centred above the
 * title in the mobile stack. Portrait crop, 4:5; the frame is a hairline a gap outside the photo. */
.sk-portrait {
  float: right;
  width: var(--sk-portrait-w);
  margin: 0 0 var(--sk-space-3) var(--sk-space-5);
  padding: var(--sk-portrait-gap);
}
.sk-portrait img, .sk-portrait-empty { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; }
.sk-portrait-empty { display: flex; align-items: center; justify-content: center; padding: var(--sk-space-2); text-align: center; }
/* In the mobile stack the portrait is centred below the header, above the title (same width as
 * the nav-collapse media query above; it follows the portrait's own rule so it wins). */
@media (max-width: 55rem) {
  .sk-portrait { float: none; width: var(--sk-portrait-w-mobile); margin: 0 auto var(--sk-space-4); }
}
.sk-title { margin: 0 0 var(--sk-space-2); }
.sk-roleline { margin: 0 0 var(--sk-space-4); }
.sk-rule { width: var(--sk-rule-width); margin: var(--sk-space-4) 0; }
.sk-footer .sk-rule { margin-top: var(--sk-space-6); }
/* The footer contact block: one line under the rule, items separated by space alone — no dot or
 * bullet (Cam, 2026-10-23) — wrapping between items, never inside one; stacked, one item per line,
 * below the nav-collapse width. */
.sk-contact { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sk-space-1) var(--sk-space-4); }
.sk-contact li { white-space: nowrap; }
@media (max-width: 55rem) {
  .sk-contact { flex-direction: column; gap: var(--sk-space-1); }
}

.sk-section { margin-top: var(--sk-section-gap); }
.sk-heading { margin: var(--sk-section-gap) 0 var(--sk-space-2); }

.sk-prose p, .sk-section p { margin: 0 0 var(--sk-space-3); }
.sk-list, .sk-links { margin: 0; padding-left: var(--sk-space-4); }
.sk-links { list-style: none; padding-left: 0; }
.sk-writing li { margin-bottom: 0; }
.sk-prose ul:not(.sk-links) { list-style: none; padding-left: var(--sk-list-indent); }
.sk-prose ul:not(.sk-links) li { position: relative; }
.sk-prose ul:not(.sk-links) li::before {
  position: absolute;
  left: calc(-1 * var(--sk-list-indent));
  top: var(--sk-rose-bullet-top);
  width: var(--sk-rose-bullet-size);
  height: var(--sk-rose-bullet-size);
}
.sk-publications, .sk-prose ol { margin: 0; padding-left: var(--sk-roman-indent); }
/* Lists sit 2rem in from the text's left margin, with half a line (plus the paragraph gap) above
 * and below (Cam, 2026-10-26); a list nested in a list adds no extra space. */
.sk-prose ul, .sk-prose ol { margin: calc(var(--sk-space-3) + 0.5lh) 0 calc(var(--sk-space-3) + 0.5lh) var(--sk-list-inset); }
.sk-prose li ul, .sk-prose li ol { margin-top: 0; margin-bottom: 0; }
/* A list that opens or closes a quote, callout or alert keeps half a line from the panel's edge. */
.sk-prose blockquote > ul:first-child, .sk-prose blockquote > ol:first-child { margin-top: 0.5lh; }
.sk-prose blockquote > ul:last-child, .sk-prose blockquote > ol:last-child { margin-bottom: 0.5lh; }
.sk-swatch { display: inline-block; width: var(--sk-swatch-w); height: var(--sk-swatch-h); margin: 0 var(--sk-space-1); vertical-align: var(--sk-swatch-raise); border-radius: var(--sk-radius-inline); }
/* A palette entry (a list item holding a swatch) reads as three aligned columns — name, swatch, the
 * light / dark hex pair — on every screen (Cam, 2026-10-26). */
.sk-prose li:has(> .sk-swatch) { display: grid; grid-template-columns: var(--sk-palette-label) auto 1fr; align-items: center; column-gap: var(--sk-space-3); }
.sk-prose li:has(> .sk-swatch) > .sk-swatch { margin: 0; }
.sk-prose li:has(> .sk-swatch) > code { justify-self: start; white-space: nowrap; }
/* Lists sit closer to the margin on a phone (Cam, 2026-10-26). */
@media (max-width: 55rem) {
  .sk-prose ul, .sk-prose ol { margin-left: var(--sk-list-inset-mobile); }
  /* On a phone the hex pair doesn't fit beside the name: name and swatch, then the pair beneath. */
  .sk-prose li:has(> .sk-swatch) { grid-template-columns: var(--sk-palette-label) 1fr; column-gap: var(--sk-space-2); row-gap: var(--sk-space-1); }
  .sk-prose li:has(> .sk-swatch) > code { grid-column: 1 / -1; }
}
.sk-publications li { padding-left: var(--sk-space-1); }
/* About half a line between list items (Cam, 2026-10-25). */
.sk-prose li + li, .sk-writing li + li { margin-top: var(--sk-list-item-gap); }
/* Code: a small inset box inline; a boxed block that scrolls sideways rather than wrapping. */
.sk-prose code { padding: 0 var(--sk-space-1); border-radius: var(--sk-radius-inline); }
.sk-prose pre { margin: 0 0 var(--sk-space-3); padding: var(--sk-space-3) var(--sk-space-4); overflow-x: auto; tab-size: 2; border-radius: var(--sk-radius-code); }
.sk-prose pre code { padding: 0; }

/* Quotes, callouts and alerts (colours in base.css). */
.sk-prose blockquote { margin: calc(var(--sk-space-3) + 0.5lh) var(--sk-space-6); padding: 0; }
.sk-prose .sk-callout, .sk-prose .sk-alert { margin-top: calc(var(--sk-space-3) + 1lh); margin-bottom: calc(var(--sk-space-3) + 1lh); }
@media (max-width: 55rem) {
  .sk-prose blockquote { margin-left: var(--sk-space-3); margin-right: var(--sk-space-3); }
}
.sk-prose .sk-callout, .sk-prose .sk-alert { padding: var(--sk-space-2) var(--sk-space-3); border-radius: var(--sk-radius-panel); }
.sk-prose blockquote > :last-child { margin-bottom: 0; }
.sk-callout-title { margin: 0 0 var(--sk-space-1); }

img { max-width: 100%; height: auto; }

.sk-skip {
  position: absolute;
  z-index: 3;   /* above the isolated leaf, so the focused link shows (Codex #74) */
  left: var(--sk-space-3);
  top: calc(-1 * var(--sk-space-6));
  padding: var(--sk-space-2);
}
.sk-skip:focus { top: var(--sk-space-3); }

/* Desktop header spacing (Cam, 2026-10-26, option A): less room above the leaf and the header. */
@media (min-width: 55.01rem) {
  body { padding-top: var(--sk-page-top-desktop); }
  .sk-leaf { padding-top: var(--sk-leaf-padding-top-desktop); }
}

/* The opening (Cam, 2026-10-26): everything before the first section fills the first screen, and a
 * "Continue" cue at its foot links to the first section. The offsets are the space above the
 * opening — page top, leaf rule and padding, header, header gap — as tokens. svh is the screen
 * height with a phone's browser bars showing. */
.sk-opening { display: flow-root; position: relative; padding-bottom: var(--sk-cue-space); }
.sk-cue {
  position: absolute;
  left: 50%;
  bottom: var(--sk-cue-bottom);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sk-space-1);
}
.sk-cue-chevron { width: var(--sk-space-4); height: var(--sk-space-3); }
.sk-cue-word { line-height: var(--sk-line-height-body); }   /* fixes the cue's height (--sk-cue-height) */
@media (min-width: 55.01rem) {
  /* The opening's content sits midway between the header's rule and the cue (Cam, 2026-10-26): the
   * opening is a column, the content block's auto margins share the spare height, and the bottom
   * padding is the cue's own height and offset plus a header-gap, to match the gap under the header.
   * The content block is a float container, so the portrait still wraps the opening text. */
  .sk-opening { min-height: calc(100vh - var(--sk-opening-offset-desktop)); min-height: calc(100svh - var(--sk-opening-offset-desktop)); display: flex; flex-direction: column; padding-bottom: calc(var(--sk-cue-bottom) + var(--sk-cue-height) + var(--sk-header-gap)); }
  .sk-opening-body { display: flow-root; margin-top: auto; margin-bottom: auto; }
  .sk-opening-text > .sk-prose > :last-child { margin-bottom: 0; }
  .sk-lead { display: contents; }
  /* The rose before section I sits midway between the cue and the heading (Cam, 2026-10-26): the
   * cue's own offset is the gap above it, the heading's top margin the equal gap below. */
  .sk-opening + .sk-section { margin-top: 0; }
  .sk-cue-lead { display: none; }
}
@media (max-width: 55rem) {
  /* Phones fill the LARGE viewport (100lvh), so nothing of the next screen shows even where the browser's
   * bar floats over the page (iPhone Safari, iOS 26); the cue is lifted by (100lvh − 100svh) so it stays
   * above a bar that does take room. Where both are equal, nothing changes (Cam, 2026-10-26). */
  .sk-opening { min-height: calc(100vh - var(--sk-opening-offset-mobile)); min-height: calc(100lvh - var(--sk-opening-offset-mobile)); padding-bottom: calc(var(--sk-cue-space) + 100lvh - 100svh); }
  .sk-opening .sk-cue { bottom: calc(var(--sk-cue-bottom) + 100lvh - 100svh); }
  /* Once scrolled, iPhone Safari also draws the page under the status bar, so a screen shows a little
   * more than 100lvh; 4rem more room before section I keeps its rose below the bottom edge (Cam,
   * 2026-10-26). The extra space is always off-screen. */
  .sk-opening + .sk-section { margin-top: calc(var(--sk-space-6) + var(--sk-space-3)); }
  /* …and the rose stays midway between the cue and the heading: the gap below it matches that room
   * plus the cue's offset (Cam, 2026-10-26). */
  .sk-opening + .sk-section::before { margin-bottom: calc(var(--sk-cue-bottom) + var(--sk-space-6) + var(--sk-space-3)); margin-bottom: calc(var(--sk-cue-bottom) + 100lvh - 100svh + var(--sk-space-6) + var(--sk-space-3)); }
  /* Home on a phone: portrait, title and role line fill the first screen; the opening text the next. */
  .sk-opening-body { display: contents; }
  .sk-opening-staged { min-height: 0; padding-bottom: 0; }
  /* Each staged screen is a column whose content is centred between its top edge — the header's rule
   * on the first screen, the top of the screen on the second — and the cue (Cam, 2026-10-26): the
   * auto margins above and below the content share the spare height equally, and the first screen's
   * cue keeps a header-gap above it to match the gap under the header. */
  .sk-opening-staged .sk-lead { display: flex; flex-direction: column; min-height: calc(100vh - var(--sk-opening-offset-mobile)); min-height: calc(100lvh - var(--sk-opening-offset-mobile)); padding-bottom: var(--sk-cue-bottom); padding-bottom: calc(var(--sk-cue-bottom) + 100lvh - 100svh); }
  .sk-opening-staged .sk-lead > .sk-portrait { margin-top: auto; }
  .sk-opening-staged .sk-lead > .sk-rule { margin-top: 0; margin-bottom: auto; }
  .sk-opening-staged .sk-lead > .sk-cue { margin-top: var(--sk-header-gap); }
  .sk-opening-staged .sk-opening-text { display: flex; flex-direction: column; min-height: 100vh; min-height: 100lvh; padding: var(--sk-header-gap) 0 var(--sk-cue-bottom); padding-bottom: calc(var(--sk-cue-bottom) + 100lvh - 100svh); scroll-margin-top: 0; }
  .sk-opening-staged .sk-opening-text > .sk-prose { margin-top: auto; margin-bottom: auto; }
  .sk-opening-staged .sk-opening-text > .sk-prose > :last-child { margin-bottom: 0; }
  .sk-opening-staged .sk-opening-text > .sk-cue { margin-top: var(--sk-header-gap); }
  .sk-opening-staged .sk-cue { position: static; transform: none; align-self: center; }
}
.sk-main .sk-section, .sk-opening-text, .sk-heading { scroll-margin-top: var(--sk-space-4); }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* A subsubsection (#### and its text) sits slightly in from its section (Cam, 2026-10-26). */
.sk-subsubsection { margin-left: var(--sk-space-4); }
@media (max-width: 55rem) {
  .sk-subsubsection { margin-left: var(--sk-space-3); }
}
/* A framed review element (or a pair) inside a subsubsection spans the full text column, so its frame is
 * centred on the page like the callouts, not pushed right by the inset (Cam, 2026-10-26). */
.sk-subsubsection > [data-ch-review], .sk-subsubsection > .sk-review-pair { margin-left: calc(-1 * var(--sk-space-4)); width: calc(100% + var(--sk-space-4)); }
@media (max-width: 55rem) {
  .sk-subsubsection > [data-ch-review], .sk-subsubsection > .sk-review-pair { margin-left: calc(-1 * var(--sk-space-3)); width: calc(100% + var(--sk-space-3)); }
}

.sk-gallery { margin: calc(var(--sk-space-3) + 0.5lh) 0; }
.sk-gallery-strip { display: flex; gap: var(--sk-space-3); overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; padding: 0 0 var(--sk-space-2); }
.sk-gallery-item { flex: 0 0 var(--sk-gallery-thumb-w); scroll-snap-align: start; }
.sk-gallery-item img { display: block; width: 100%; height: auto; border-radius: var(--sk-radius-inline); }
.sk-gallery-label { display: block; font-size: var(--sk-font-size-small); margin-top: var(--sk-space-1); }
.sk-lightbox { display: none; }
.sk-lightbox:target { display: flex; flex-direction: column; align-items: center; justify-content: center; position: fixed; inset: 0; z-index: 20; padding: var(--sk-space-4); }
.sk-lightbox-backdrop { position: absolute; inset: 0; }
.sk-lightbox-figure { position: relative; margin: 0; max-width: 100%; text-align: center; }
.sk-lightbox-figure img { display: block; width: auto; height: auto; max-width: min(100%, var(--sk-lightbox-max-w)); max-height: calc(100vh - var(--sk-lightbox-chrome)); margin: 0 auto; border-radius: var(--sk-radius-inline); }
.sk-lightbox-figure figcaption { font-size: var(--sk-font-size-small); margin-top: var(--sk-space-2); }
.sk-lightbox-nav { position: relative; display: flex; gap: var(--sk-space-5); justify-content: center; margin-top: var(--sk-space-3); }
.sk-lightbox-nav a { display: inline-flex; align-items: center; min-height: var(--sk-touch-target); }
@media (max-width: 55rem) {
  .sk-gallery-item { flex-basis: var(--sk-gallery-thumb-w-mobile); }
  .sk-lightbox:target { padding: var(--sk-space-2); }
}

/* Teaching-review elements: geometry (colours and faces in base.css). The plain edition sits flush
 * with the text; the illustrated edition is a framed plate. */
[data-ch-review] { display: block; width: 100%; min-width: 0; margin: calc(var(--sk-space-3) + 0.5lh) 0; padding: 0; line-height: 1.55; text-align: left; overflow-wrap: break-word; }
[data-ch-review] *, [data-ch-review] *::before, [data-ch-review] *::after { box-sizing: border-box; }
[data-ch-review] .chr-heading { display: block; font-size: var(--sk-rv-heading-size); line-height: 1.35; margin: 0 0 var(--sk-space-3); }
[data-ch-review] .chr-quotation { display: block; margin: 0 0 var(--sk-space-3); padding: 0 0 0 var(--sk-space-3); }
[data-ch-review] .chr-quotation p { font-size: var(--sk-rv-quote-size); line-height: 1.55; margin: 0; padding: 0; }
[data-ch-review] p.chr-attribution { font-size: var(--sk-rv-fs-attribution); line-height: 1.6; margin: 0; }
[data-ch-review] p.chr-value { font-size: var(--sk-rv-number-size); line-height: 1.15; margin: var(--sk-space-2) 0; white-space: nowrap; }
[data-ch-review] .chr-value small { font-size: var(--sk-space-3); }
[data-ch-review] p.chr-count { font-size: var(--sk-rv-fs-m); margin: 0 0 var(--sk-space-3); }
[data-ch-review] p.chr-note { font-size: var(--sk-rv-fs-m); line-height: 1.6; margin: var(--sk-space-3) 0 0; }
[data-ch-review] .chr-sources { display: block; font-size: var(--sk-rv-fs-s); margin: var(--sk-space-4) 0 0; padding: var(--sk-space-2) 0 0; }
[data-ch-review] .chr-sources summary { display: list-item; font-size: var(--sk-rv-fs-summary); margin: 0; padding: var(--sk-space-1) 0; }
[data-ch-review] .chr-sources p { font-size: var(--sk-rv-fs-s); line-height: 1.6; margin: var(--sk-space-2) 0; }
[data-ch-review] .chr-sources p.chr-filename { font-size: var(--sk-rv-fs-xs); overflow-wrap: anywhere; }
[data-ch-review] .chr-chart { display: block; margin: var(--sk-space-4) 0; }
[data-ch-review] .chr-row { display: block; margin: 0; padding: var(--sk-space-3) 0; }
[data-ch-review] .chr-row-head { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: var(--sk-space-2) var(--sk-space-3); margin: 0 0 var(--sk-space-3); }
[data-ch-review] .chr-row-label { display: block; flex: 1 1 var(--sk-rv-label-basis); font-size: var(--sk-space-3); line-height: 1.4; }
[data-ch-review] .chr-row-value { display: block; font-size: var(--sk-space-3); white-space: nowrap; }
[data-ch-review] .chr-row-value small { display: block; font-size: var(--sk-rv-fs-xs); line-height: 1.6; }
[data-ch-review] .chr-track { display: block; position: relative; height: var(--sk-rv-track-h); margin: 0 var(--sk-space-2); }
[data-ch-review] .chr-track::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; }
[data-ch-review] .chr-point { display: block; position: absolute; left: var(--chr-position); top: 50%; width: var(--sk-rv-point); height: var(--sk-rv-point); transform: translate(-50%, -50%) rotate(45deg); }
[data-ch-review] .chr-ticks { display: flex; justify-content: space-between; font-size: var(--sk-rv-fs-xs); margin: var(--sk-space-1) var(--sk-space-1) 0; }
/* The illustrated edition: a framed plate with an inner hairline, a kicker, and its art. */
[data-illustrated="true"] { position: relative; isolation: isolate; padding: var(--sk-rv-pad-illustrated); }
[data-illustrated="true"]::before { content: ''; position: absolute; inset: var(--sk-rv-inset); pointer-events: none; z-index: -1; }
[data-illustrated="true"] .chr-kicker { display: flex; justify-content: space-between; gap: var(--sk-space-3); align-items: center; padding: 0 0 var(--sk-space-3); margin: 0 0 var(--sk-space-4); font-size: var(--sk-rv-fs-kicker); }
[data-illustrated="true"] .chr-kicker span { font-size: var(--sk-space-3); line-height: 1; }
[data-illustrated="true"] .chr-illustration { display: block; height: auto; max-width: 100%; object-fit: contain; }
[data-illustrated="true"] .chr-heading { font-size: var(--sk-rv-heading-size-illustrated); line-height: 1.25; margin-bottom: var(--sk-space-4); }
[data-illustrated="true"] .chr-quote-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sk-space-4); align-items: center; }
[data-illustrated="true"] .chr-copy { min-width: 0; position: relative; }
[data-illustrated="true"][data-art="book"] .chr-quote-layout { grid-template-columns: minmax(var(--sk-rv-book-min), 0.65fr) minmax(0, 2fr); gap: var(--sk-space-5); }
[data-illustrated="true"][data-art="book"] .chr-illustration { width: 100%; max-height: var(--sk-rv-book-max-h); }
[data-illustrated="true"] .chr-opening-mark { display: block; font-size: var(--sk-rv-mark-size); line-height: 0.65; margin: var(--sk-space-3) 0 calc(-1 * var(--sk-space-1)); }
[data-illustrated="true"] .chr-quotation { padding: 0; margin: 0 0 var(--sk-space-4); }
[data-illustrated="true"] .chr-quotation p { font-size: var(--sk-rv-quote-size-illustrated); line-height: 1.5; }
[data-illustrated="true"] p.chr-attribution { font-size: var(--sk-rv-fs-xs); line-height: 1.7; }
[data-illustrated="true"][data-kind="metric"] > .chr-illustration { width: var(--sk-rv-spray-w); margin: 0 auto var(--sk-space-3); }
[data-illustrated="true"][data-kind="metric"] .chr-heading { max-width: var(--sk-rv-label-basis); text-align: center; margin: 0 auto var(--sk-space-3); }
[data-illustrated="true"] p.chr-value { text-align: center; font-size: var(--sk-rv-number-size-illustrated); line-height: 1.05; }
[data-illustrated="true"] .chr-value small { font-size: var(--sk-font-size-h3); }
[data-illustrated="true"][data-kind="metric"] p.chr-count { text-align: center; margin: 0 0 var(--sk-space-4); }
[data-illustrated="true"][data-kind="metric"] p.chr-attribution { padding-top: var(--sk-space-3); }
[data-illustrated="true"] .chr-chart-title { display: flex; align-items: center; justify-content: space-between; gap: var(--sk-space-3); margin-bottom: var(--sk-space-4); }
[data-illustrated="true"] .chr-chart-title .chr-heading { max-width: 65%; margin: 0; }
[data-illustrated="true"] .chr-chart-title .chr-heading:only-child { max-width: none; }
[data-illustrated="true"] .chr-chart-title .chr-illustration { width: var(--sk-rv-chart-art-w); max-width: 32%; }
[data-illustrated="true"] .chr-row { padding: var(--sk-space-3) 0 var(--sk-space-3); }
[data-illustrated="true"] .chr-track::after { content: ''; position: absolute; left: 0; top: 50%; width: var(--chr-position); transform: translateY(-50%); }
[data-illustrated="true"] .chr-point { z-index: 1; }
[data-illustrated="true"] p.chr-note { font-size: var(--sk-rv-fs-s); }
[data-illustrated="true"] .chr-sources { margin-top: var(--sk-space-4); }
/* Two elements side by side (a pair of charts), stacked on a phone. */
.sk-review-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sk-space-5); align-items: start; margin: calc(var(--sk-space-3) + 0.5lh) 0; }
.sk-review-pair > [data-ch-review] { margin: 0; }
/* The rose vine from the Overall teaching exhibit, centred over the pair (Cam, 2026-10-27). */
.sk-pair-ornament { display: block; grid-column: 1 / -1; width: var(--sk-rv-spray-w); max-width: 100%; height: auto; margin: 0 auto; }
.sk-pair-heading, .sk-pair-tag { display: none; }
@media (max-width: 55rem) {
  [data-illustrated="true"] { padding: var(--sk-space-4); }
  [data-illustrated="true"][data-art="book"] .chr-quote-layout { grid-template-columns: minmax(0, 1fr); gap: var(--sk-space-3); }
  [data-illustrated="true"][data-art="book"] .chr-illustration { width: var(--sk-rv-book-mobile-w); max-height: var(--sk-rv-book-mobile-h); margin: 0 auto; }
  [data-illustrated="true"] .chr-quote-layout .chr-heading { text-align: center; }
  [data-illustrated="true"] .chr-opening-mark { font-size: var(--sk-rv-mark-size-mobile); }
  [data-illustrated="true"] .chr-chart-title { align-items: start; }
  /* On a phone the pair is one framed exhibit and one list (Cam, 2026-10-26): the pair takes the
   * illustrated frame and a single heading; the two charts dissolve into it (display: contents) and their
   * parts are reordered, so each chart's heading becomes a group label over its rows, and both charts'
   * notes and sources follow the last row. */
  .sk-review-pair { grid-template-columns: minmax(0, 1fr); gap: 0; position: relative; isolation: isolate; box-sizing: border-box; padding: var(--sk-space-4); }
  .sk-review-pair::before { content: ''; position: absolute; inset: var(--sk-rv-inset); pointer-events: none; z-index: -1; }
  .sk-review-pair > [data-ch-review] { display: contents; }
  .sk-review-pair .chr-kicker, .sk-review-pair .chr-heading-rest { display: none; }
  .sk-review-pair .sk-pair-tag { display: inline; }
  .sk-pair-ornament { order: -1; margin-bottom: var(--sk-space-3); }
  .sk-pair-heading { display: block; order: 0; font-size: var(--sk-rv-heading-size-illustrated); line-height: 1.25; margin: 0 0 var(--sk-space-4); }
  .sk-review-pair .chr-heading, .sk-review-pair .chr-chart-title { margin: 0 0 var(--sk-space-1); max-width: none; }
  .sk-review-pair .chr-heading { font-size: var(--sk-rv-fs-kicker); line-height: 1.4; }
  .sk-review-pair p.chr-attribution { padding-top: 0; margin: 0; }
  .sk-review-pair .chr-chart { margin: var(--sk-space-2) 0 var(--sk-space-4); }
  .sk-review-pair > figure:nth-of-type(1) > .chr-heading { order: 1; }
  .sk-review-pair > figure:nth-of-type(1) > .chr-attribution { order: 2; }
  .sk-review-pair > figure:nth-of-type(1) > .chr-chart { order: 3; }
  .sk-review-pair > figure:nth-of-type(2) > .chr-chart-title { order: 4; padding-top: var(--sk-space-3); }
  .sk-review-pair > figure:nth-of-type(2) > .chr-attribution { order: 5; }
  .sk-review-pair > figure:nth-of-type(2) > .chr-chart { order: 6; }
  .sk-review-pair > figure:nth-of-type(1) > .chr-note { order: 7; margin: 0 0 var(--sk-space-2); }
  .sk-review-pair > figure:nth-of-type(2) > .chr-note { order: 8; margin: 0; }
  .sk-review-pair > figure:nth-of-type(1) > .chr-sources { order: 9; }
  .sk-review-pair > figure:nth-of-type(2) > .chr-sources { order: 10; margin-top: 0; border-top: 0; }
}
/* Docclean exhibit: the scan centred on top, then plain extraction and Docclean side by side,
 * stacked on a narrow screen. */
.dc-exhibit { display: block; position: relative; isolation: isolate; box-sizing: border-box; width: 100%; max-width: var(--sk-measure); margin: var(--sk-space-5) auto; padding: var(--sk-rv-pad-illustrated); }
.dc-exhibit::before { content: ''; position: absolute; inset: var(--sk-rv-inset); pointer-events: none; z-index: -1; }
.dc-exhibit * { box-sizing: border-box; }
.dc-exhibit .dc-scanrow { text-align: center; margin: 0 0 var(--sk-dc-scan-gap); }
.dc-exhibit .dc-scan { display: block; width: 100%; max-width: var(--sk-dc-scan-max); height: auto; margin: var(--sk-space-1) auto 0; }
.dc-exhibit .dc-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0; align-items: start; padding-top: var(--sk-space-3); }
.dc-exhibit .dc-col { min-width: 0; }
.dc-exhibit .dc-plain { padding-right: var(--sk-dc-gutter); }
.dc-exhibit .dc-output { padding-left: var(--sk-dc-gutter); }
.dc-exhibit .dc-label { font-size: var(--sk-dc-fs-label); line-height: 1.2; margin: 0 0 var(--sk-space-1); }
.dc-exhibit .dc-sub { font-size: var(--sk-rv-fs-s); line-height: 1.35; margin: 0 0 var(--sk-dc-sub-gap); }
.sk-prose .dc-exhibit pre.dc-pre { font-size: var(--sk-dc-fs-pre); line-height: 1.5; white-space: pre-wrap; overflow-wrap: break-word; word-break: normal; overflow-x: visible; margin: 0; padding: 0; border-radius: 0; }
@media (max-width: 55rem) {
  .dc-exhibit { padding: var(--sk-space-4); }
  .dc-exhibit .dc-grid { grid-template-columns: 1fr; }
  .dc-exhibit .dc-plain { padding-right: 0; margin-bottom: var(--sk-dc-stack-gap); }
  .dc-exhibit .dc-output { padding-left: 0; padding-top: var(--sk-dc-stack-gap); }
}
/* CV rows (Cam's table syntax for side-by-side items): the date in its own column beside the entry;
 * stacked on a phone. */
.sk-prose .sk-cv-rows { display: grid; gap: var(--sk-space-3); margin: 0 0 var(--sk-space-4); }
.sk-prose .sk-cv-row { display: grid; grid-template-columns: var(--sk-cv-date-w) minmax(0, 1fr); column-gap: var(--sk-space-4); align-items: baseline; }
.sk-prose .sk-cv-row p { margin: 0; }
.sk-prose .sk-cv-date { font-size: var(--sk-font-size-small); }
.sk-prose .sk-cv-meta { font-size: var(--sk-font-size-small); margin-top: var(--sk-space-1); }
@media (max-width: 55rem) {
  .sk-prose .sk-cv-row { grid-template-columns: minmax(0, 1fr); }
  .sk-prose .sk-cv-date { margin-bottom: var(--sk-space-1); }
}
/* The CV's PDF link: a centred box, shrunk to the link, double hairline, a rose either side. */
.sk-prose .sk-cv-pdf { display: flex; align-items: center; justify-content: center; gap: var(--sk-space-3); width: fit-content; max-width: 100%; box-sizing: border-box; margin: var(--sk-space-5) auto; padding: var(--sk-space-3) var(--sk-space-4); position: relative; isolation: isolate; text-align: center; }
.sk-prose .sk-cv-pdf::before { content: ''; position: absolute; inset: var(--sk-rv-inset); pointer-events: none; z-index: -1; }
.sk-cv-pdf-rose { display: block; flex: none; width: var(--sk-divider-size); height: var(--sk-divider-size); }
@media (max-width: 55rem) {
  .sk-prose .sk-cv-pdf { gap: var(--sk-space-2); padding: var(--sk-space-3); }
  .sk-prose .sk-cv-pdf a { font-size: var(--sk-font-size-small); white-space: nowrap; }
}
/* Document lists: a box framed like the exhibits. */
.sk-prose .sk-doclist { position: relative; isolation: isolate; margin: calc(var(--sk-space-3) + var(--sk-doclist-medallion) / 2) 0 var(--sk-space-4); padding: calc(var(--sk-space-3) + var(--sk-space-1)) var(--sk-space-5) var(--sk-space-3); border-radius: var(--sk-doclist-radius); }
.sk-prose .sk-doclist::before { content: ''; position: absolute; inset: var(--sk-rv-inset); border-radius: calc(var(--sk-doclist-radius) - var(--sk-rv-inset)); pointer-events: none; z-index: -1; }
.sk-prose .sk-doclist::after, .sk-prose .sk-doclist > ul::before { content: ''; position: absolute; left: 50%; top: 0; transform: translate(-50%, -50%); pointer-events: none; }
.sk-prose .sk-doclist::after { width: var(--sk-doclist-medallion); height: var(--sk-doclist-medallion); box-sizing: border-box; }
.sk-prose .sk-doclist > ul::before { width: var(--sk-divider-size); height: var(--sk-divider-size); z-index: 1; }
.sk-prose .sk-doclist > ul { margin: 0; }
.sk-prose .sk-doclist li + li { margin-top: 0; }   /* rows are already touch-target tall */
@media (max-width: 55rem) {
  .sk-prose .sk-doclist { padding: var(--sk-space-3) var(--sk-space-4); }
}
