/* panel-record — yours to edit.
 *
 * The panel's own surface, not the client's: this is the record, not the site.
 * Appearance only. The primitive sets visibility, inert and position.
 */

.nods-panel {
  /* How long the panel takes to leave. The script reads this and keeps the
   * panel painted that long after a close, with `data-nods-closing` on it,
   * so the leaving below is seen. A template with its own exit sets its own. */
  --nods-exit: 140ms;
  width: var(--nods-panel-w, 20rem);
  max-width: calc(100vw - 2rem);
  background: var(--nods-panel-bg, #fff);
  color: var(--nods-panel-fg, #14171a);
  border: 1px solid var(--nods-panel-line, #e6e9ed);
  border-radius: var(--nods-panel-radius, 10px);
  box-shadow: 0 1px 2px rgb(16 20 24 / 6%), 0 12px 32px -8px rgb(16 20 24 / 18%);
  z-index: 60;
  opacity: 0;

  /* The reveal, which is this product's one moment of motion and was a default:
   * six pixels of translate and a fade, centred on nothing.
   *
   * Three things make it a designed one.
   *
   * It grows from the word that opened it. --nods-origin-x is the disclosure
   * button's centre, set by the primitive at placement time, and the vertical
   * half is the edge nearest the button — so a card opening upward expands from
   * its bottom edge rather than inflating around its middle.
   *
   * The scale is small and the translate is small. A card is handed over, not
   * launched; anything past about 4% reads as a bounce.
   *
   * In and out are not the same length. Arriving is 240ms on the house curve,
   * which decelerates hard and settles; leaving is 140ms and linear-ish,
   * because a dismissal the visitor has already decided on should not be
   * narrated back at them. Equal durations are the single most common sign
   * that nobody chose either. */
  transform: translateY(var(--nods-rise, 6px)) scale(var(--nods-pop, 0.97));
  transform-origin: var(--nods-origin-x, 50%) bottom;
  transition: opacity 140ms ease-out, transform 140ms ease-out;
}

.nods-panel[data-nods-open] {
  opacity: 1;
  transform: none;
  transition: opacity 240ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 240ms cubic-bezier(0.16, 1, 0.3, 1);
}

.nods-panel[data-nods-flip="below"] {
  transform: translateY(calc(var(--nods-rise, 6px) * -1)) scale(var(--nods-pop, 0.97));
  transform-origin: var(--nods-origin-x, 50%) top;
}
.nods-panel[data-nods-flip="below"][data-nods-open] { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .nods-panel,
  .nods-panel[data-nods-open] { transform: none; transition: opacity 120ms linear; }
}

.pr { padding: 0.9rem 0.95rem 0.85rem; font-size: 0.8125rem; line-height: 1.45; }

.pr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.pr-title { margin: 0; font-size: 1rem; font-weight: 500; letter-spacing: -0.012em; }
.pr-year { font-variant-numeric: tabular-nums; opacity: 0.62; font-size: 0.75rem; }
.pr-since { margin: 0.2rem 0 0; opacity: 0.62; font-size: 0.72rem; }

.pr-list {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0.6rem 0 0;
  border-top: 1px solid var(--nods-panel-line, #e6e9ed);
  display: grid;
  gap: 0.1rem;
}
.pr-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 0.9rem; }
.pr-role { opacity: 0.62; white-space: nowrap; }
/* No opacity here: the degree is nested INSIDE .pr-role, so a second
 * opacity multiplies with its parent's and lands at 2.8:1. It is already
 * muted by the role; size alone separates it. */
.pr-degree { font-size: 0.9em; }
.pr-list li[data-lead] .pr-role { opacity: 0.8; }
.pr-list li[data-lead] .pr-who { font-weight: 500; }
.pr-who { color: inherit; text-decoration: none; text-align: right; border-bottom: 1px solid transparent; }
.pr-who:hover, .pr-who:focus-visible { border-bottom-color: currentColor; }

.pr-with {
  margin: 0.7rem 0 0;
  padding-top: 0.6rem;
  border-top: 1px solid var(--nods-panel-line, #e6e9ed);
  font-size: 0.72rem;
  opacity: 0.62;
}

.pr-foot { margin-top: 0.75rem; padding-top: 0.6rem; border-top: 1px solid var(--nods-panel-line, #e6e9ed); }
.pr-more {
  font-size: 0.68rem; letter-spacing: 0.07em; text-transform: uppercase;
  color: inherit; opacity: 0.62; text-decoration: none;
}
.pr-more:hover, .pr-more:focus-visible { opacity: 1; }

/* Licence and claims.
 *
 * .62 not .55: on the white panel surface .55 measures 3.99:1, under the 4.5
 * an 11px line needs. Checked with getComputedStyle, not by eye.
 */
.pr-lic {
  margin: 0.45rem 0 0;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.pr-claims {
  margin: 0.2rem 0 0;
  font-size: 0.72rem;
  opacity: 0.62;
}

.pr-measured {
  margin: 0.2rem 0 0;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.62;
}

/* The date is never optional on a figure, so it gets its own line rather than
 * competing for space on the first. */
.pr-when { display: block; font-size: 0.92em; }

/* panel-poster — yours to edit.
 *
 * A poster with the maker's name on it, and it has no colours of its own:
 * every part is set from a custom property, and what is below is a poster in
 * black and paper.
 *
 *   --po-bg, --po-ink                the sheet and what is printed on it
 *   --po-band-bg, --po-band-ink      the ticker along the foot
 *   --po-seal-bg, --po-seal-ink      the seal on the edge
 *   --po-display, --po-face          the name's face, and everything else's
 *   --po-name-weight, --po-name-track
 *   --po-radius, --po-pad, --po-w, --po-h
 *   --po-button-*                    the link to the maker's site
 *   --po-tick                        how long the ticker takes to come round
 */

.nods-panel:has(.po) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 340ms; }
.nods-panel:has(.po)[data-nods-closing] { opacity: 1; transform: none; }

.po {
  --_bg: var(--po-bg, var(--nods-ground, #111315));
  --_ink: var(--po-ink, var(--nods-ink, #f4f1ea));
  --_pad: var(--po-pad, var(--nods-pad, 1.25rem));
  position: relative;
  box-sizing: border-box;
  container-type: inline-size;
  width: var(--po-w, var(--nods-width, 25rem));
  max-width: 100%;
  min-height: var(--po-h, 19rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto 1fr auto;
  padding: var(--_pad) var(--_pad) 0;
  background: var(--_bg);
  color: var(--_ink);
  border-radius: var(--po-radius, var(--nods-radius, 0));
  font-family: var(--po-face, var(--nods-face, inherit));
  font-size: 0.9375rem;
  line-height: 1.35;
  text-align: left;
}
.po p { margin: 0; }
.po-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* What was done, on what, and when: small, in the corner a poster dates
 * itself in. */
.po-top { display: flex; flex-wrap: wrap; font-family: var(--po-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; }
/* The point goes with the word before it, so a line never starts with one. */
.po-top span { white-space: nowrap; }
.po-top span:not(:last-child)::after { content: "\00a0\00b7\00a0"; }

/* The name, as wide as the sheet. Its size is the sheet's width over the
 * number of letters it has to fit, so a short name is enormous and a long
 * one still fills the line it is given. Each word is a window its letters
 * rise into. */
.po-name {
  margin-top: 0.35rem;
  font-family: var(--po-display, var(--nods-display, inherit));
  font-size: min(var(--po-name-max, 44cqi), calc(var(--po-name-fit, 180cqi) / var(--fit, 8)));
  font-weight: var(--po-name-weight, 800);
  line-height: 0.9;
  letter-spacing: var(--po-name-track, -0.045em);
}
.po .po-name { margin-top: 0.4rem; margin-left: -0.07em; }
.po-w { display: inline-block; overflow: hidden; padding: 0.04em 0.06em 0.14em 0; margin-bottom: -0.14em; white-space: nowrap; vertical-align: top; }
.po-l { display: inline-block; }
.po[data-long] .po-name { text-wrap: balance; }

.po .po-line { margin-top: 0.75rem; max-width: min(22ch, calc(100% - var(--po-seal-size, 6.5rem) + 1.9rem)); font-size: 1.1875rem; font-weight: 500; line-height: 1.22; letter-spacing: -0.015em; text-wrap: balance; }

/* The two ways to the maker, together at the left: the right of the sheet
 * is the seal's. */
.po-foot { align-self: end; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1rem; padding: 1rem 0 0.95rem; padding-right: calc(var(--po-seal-size, 6.5rem) - 1.6rem); }
/* The way to the maker: the address, heavy, on a thick rule. A poster does
 * not have a button on it. */
.po-site {
  padding: var(--po-button-pad, 0 0 0.12em);
  background: var(--po-button-bg, none);
  color: var(--po-button-ink, inherit);
  border-radius: var(--po-button-radius, 0);
  border-bottom: 2px solid currentColor;
  font-size: 1rem; font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; text-decoration: none;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.po-site::after { content: "\00a0\2197"; }
.po-page { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; font-size: 0.8125rem; text-decoration: none; border-bottom: 1px solid color-mix(in oklch, currentColor 45%, transparent); }
.po-site:hover { border-bottom-width: 3px; }
.po-page:hover { border-bottom-color: currentColor; }
.po a:focus-visible { outline: 2px solid var(--_ink); outline-offset: 3px; }

/* The band along the foot, edge to edge, and what runs in it. Two copies of
 * the run side by side, moved left by the width of one, so it never ends. */
.po-band {
  margin: 0 calc(var(--_pad) * -1);
  height: 2.75rem;
  display: flex; align-items: center;
  overflow: hidden;
  background: var(--po-band-bg, var(--_ink));
  color: var(--po-band-ink, var(--_bg));
  border-radius: 0 0 var(--po-radius, var(--nods-radius, 0)) var(--po-radius, var(--nods-radius, 0));
}
.po-run { display: flex; width: max-content; animation: po-run var(--po-tick, 26s) linear infinite; }
.po-run > div { display: flex; align-items: center; flex: none; }
.po-run span { padding: 0 0.85rem; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; white-space: nowrap; }
.po-star { flex: none; width: 0.8rem; height: 0.8rem; fill: currentColor; }
@keyframes po-run { to { transform: translateX(-50%); } }

/* The seal: stuck on the edge of the sheet and a third off it, which is what
 * takes the card out of its rectangle. The words go round; the star in the
 * middle stays put. */
.po-seal { position: absolute; top: 41%; right: var(--po-seal-out, -1.6rem); width: var(--po-seal-size, 6.5rem); aspect-ratio: 1; rotate: 12deg; }
/* A long name takes the lines the seal would stand on, so the seal goes down
 * to the foot. */
.po[data-long] .po-seal { top: auto; bottom: 3.4rem; }
.po-seal svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(1px 2px 0 rgb(0 0 0 / 0.16)); }
.po-seal-disc { fill: var(--po-seal-bg, var(--_ink)); }
.po-seal-text { fill: var(--po-seal-ink, var(--_bg)); font-family: var(--po-face, var(--nods-face, inherit)); font-size: 8.6px; font-weight: 600; letter-spacing: 0.04em; transform-origin: 50px 50px; animation: po-turn 28s linear infinite; }
.po-seal-star { fill: var(--po-seal-ink, var(--_bg)); }
@keyframes po-turn { to { transform: rotate(360deg); } }

/* The opening. Everything is written at its resting place, and each part
 * arrives at it from somewhere: the letters from under their line, the band
 * from the left, the seal from nothing. */
.nods-panel[data-nods-open] .po-l { animation: po-rise 640ms cubic-bezier(0.2, 0.9, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 34ms + 90ms); }
.nods-panel[data-nods-open] .po-band { animation: po-draw 560ms cubic-bezier(0.2, 0.9, 0.2, 1) 180ms both; }
/* The seal is stamped, not placed: it comes down from over the sheet, fast,
 * and the sheet takes the blow. */
.nods-panel[data-nods-open] .po-seal { animation: po-stamp 190ms cubic-bezier(0.6, 0, 0.9, 0.4) 620ms both; }
/* The sheet comes up from its foot, and what is on it then arrives. */
.nods-panel[data-nods-open] .po { animation: po-up 300ms cubic-bezier(0.2, 0.9, 0.2, 1) both, po-blow 140ms ease-out 800ms both; }
@keyframes po-up { from { clip-path: inset(100% -3rem 0 -3rem); } to { clip-path: inset(-1rem -3rem -1rem -3rem); } }
.nods-panel[data-nods-open] :is(.po-top, .po-line, .po-foot) { animation: po-in 420ms ease 320ms both; }
/* A letter comes up thin and takes its ink as it lands. */
@keyframes po-rise { from { transform: translateY(112%); font-weight: var(--po-name-thin, 300); } 55% { font-weight: var(--po-name-thin, 300); } }
@keyframes po-draw { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0); } }
@keyframes po-stamp { from { scale: 1.9; opacity: 0; } 30% { opacity: 1; } }
@keyframes po-blow { 40% { transform: translate(-1px, 2px); } }

/* Leaving: the letters drop back under their line and the sheet goes. */
.nods-panel[data-nods-closing] .po-l { animation: po-fall 200ms cubic-bezier(0.5, 0, 0.8, 0.4) both; animation-delay: calc(var(--i, 0) * 12ms); }
.nods-panel[data-nods-closing] .po { animation: po-leave 180ms ease 160ms both; }
@keyframes po-fall { to { transform: translateY(112%); } }
@keyframes po-leave { to { opacity: 0; transform: translateY(0.4rem); } }
@keyframes po-in { from { opacity: 0; transform: translateY(0.35rem); } }

@media (prefers-reduced-motion: reduce) {
  .po, .po *, .nods-panel[data-nods-open] .po, .nods-panel[data-nods-open] .po *, .nods-panel[data-nods-closing] .po, .nods-panel[data-nods-closing] .po * { animation: none !important; }
}
@media (prefers-contrast: more) { .po-page { border-bottom-color: currentColor; } }
@media print {
  .po { background: #fff; color: #000; }
  .po-band, .po-seal { display: none; }
  .po-site { background: none; color: #000; padding: 0; text-decoration: underline; }
}

/* panel-groove — yours to edit.
 *
 * A record and its sleeve. The sleeve is the maker's and takes its colours
 * from them; the record comes half out of it and turns.
 *
 *   --gv-w                         the width: the sleeve and the half of the record that shows
 *   --gv-sleeve, --gv-fg           the sleeve and what is printed on it
 *   --gv-vinyl                     the record
 *   --gv-label-bg, --gv-label-fg   its label
 *   --gv-out                       how much of the record is out of the sleeve
 *   --gv-rpm                       how long one turn takes; 1.8s is a long-player
 *   --gv-display, --gv-face, --gv-mono
 *   --gv-name-size                 the most the name may be
 */

.nods-panel:has(.gv) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 320ms; }
.nods-panel:has(.gv)[data-nods-closing] { opacity: 1; transform: none; }

.gv {
  --_w: var(--gv-w, var(--nods-width, 20.5rem));
  /* The sleeve is square, and the record is nearly as wide as it is. */
  --_s: calc(var(--_w) / (1 + var(--gv-out, 0.58) * 0.94));
  --_d: calc(var(--_s) * 0.94);
  --_bg: var(--gv-sleeve, #e8401c);
  --_ink: var(--gv-fg, var(--nods-ink, #190d09));
  position: relative;
  box-sizing: border-box;
  width: var(--_w);
  max-width: 100%;
  height: var(--_s);
  font-family: var(--gv-face, var(--nods-face, inherit));
  text-align: left;
}
.gv p { margin: 0; }

/* The record, behind the sleeve and out of it to the right. */
.gv-disc {
  position: absolute; top: 3%; left: calc(var(--_s) - var(--_d) * (1 - var(--gv-out, 0.58)));
  width: var(--_d); aspect-ratio: 1; border-radius: 50%;
  /* The spindle hole, through everything: the page shows in it. */
  -webkit-mask: radial-gradient(circle closest-side, transparent 2.6%, #000 3.4%);
  mask: radial-gradient(circle closest-side, transparent 2.6%, #000 3.4%);
}
/* What turns: the vinyl, its grooves and its label. A band of bare vinyl at
 * the rim and another round the label, as a lathe leaves them. */
.gv-turn {
  position: absolute; inset: 0; border-radius: 50%;
  background:
    /* Every radius here is a share of the disc's own, so the label is as big
     * as it says and the words on it are inside it. */
    radial-gradient(circle closest-side, var(--gv-label-bg, var(--nods-chip-ground, #efe8d9)) 0 49%, transparent 50%),
    radial-gradient(circle closest-side, transparent 0 55%, color-mix(in oklab, #fff 9%, transparent) 55.6% 56.6%, transparent 57.4%),
    repeating-radial-gradient(circle closest-side at 50% 50%, color-mix(in oklab, #fff 8%, transparent) 0 0.6px, transparent 0.6px 2.4px),
    var(--gv-vinyl, #0b0b0d);
  color: var(--gv-label-fg, var(--nods-chip-ink, #17120f));
  animation: gv-spin var(--gv-rpm, 1.8s) linear infinite;
}
@keyframes gv-spin { to { transform: rotate(360deg); } }
/* The light: two wedges across the record, which do not turn with it. */
.gv-disc::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 24deg, transparent 0 7%, rgb(255 255 255 / 0.2) 12%, transparent 18% 57%, rgb(255 255 255 / 0.13) 62%, transparent 68%);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 50%, #000 51%);
  mask: radial-gradient(circle closest-side, transparent 0 50%, #000 51%);
}
/* The label: words round it, and the side, set off-centre so that the turn
 * can be seen. */
.gv-rim { position: absolute; inset: 27%; width: 46%; height: 46%; overflow: visible; }
.gv-rim text { fill: currentColor; font-family: var(--gv-face, var(--nods-face, inherit)); font-size: 8.6px; font-weight: 600; letter-spacing: 0.02em; }
.gv-side { position: absolute; left: 50%; top: 56%; translate: -50% 0; font-size: 0.875rem; font-weight: 700; line-height: 1; }

/* The sleeve. A square of card with the maker's name on it, and the mark a
 * record leaves in a sleeve it has lived in. */
.gv-sleeve {
  position: absolute; inset: 0 auto 0 0; width: var(--_s);
  box-sizing: border-box;
  container-type: inline-size;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto 1fr;
  padding: var(--gv-pad, var(--nods-pad, 1.15rem));
  background:
    radial-gradient(circle closest-side, transparent 0 88%, rgb(0 0 0 / 0.09) 89.5% 91.5%, transparent 93%),
    var(--_bg);
  color: var(--_ink);
  border-radius: var(--gv-radius, var(--nods-radius, 0.15rem));
  /* The open edge, where the record goes in. */
  box-shadow: inset -0.3rem 0 0.35rem -0.3rem rgb(0 0 0 / 0.35), 0.15rem 0 0.4rem -0.1rem rgb(0 0 0 / 0.3);
}
.gv-role { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; }
.gv-name {
  font-family: var(--gv-display, var(--nods-display, ui-serif, Georgia, "Times New Roman", serif));
  font-size: clamp(1.375rem, calc(236cqi / (var(--n, 9) + 1)), var(--gv-name-size, 4rem));
  font-weight: var(--gv-name-weight, 400);
  line-height: 0.92;
  letter-spacing: -0.025em;
}
.gv .gv-name { margin-top: 0.35rem; margin-left: -0.03em; }
.gv-name span { display: block; white-space: nowrap; }
.gv .gv-for { margin-top: 0.5rem; font-size: 0.8125rem; line-height: 1.3; }
.gv-others { font-size: 0.6875rem; line-height: 1.35; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.gv .gv-others { margin-top: 0.3rem; align-self: start; }
.gv-links { align-self: end; display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; gap: 0.25rem; }
/* An address too long for the sleeve is cut with an ellipsis. A name never is. */
.gv-site, .gv-page { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.gv-site { font-size: 0.875rem; font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.22em; padding-bottom: 0.15em; }
.gv-page { font-family: var(--gv-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; }
.gv-page:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.gv a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 2px; }

/* Taken out of the sleeve, and put back. */
.nods-panel[data-nods-open] .gv-disc { animation: gv-out 780ms cubic-bezier(0.2, 0.85, 0.25, 1) 120ms both; }
.nods-panel[data-nods-open] .gv-sleeve { animation: gv-in 420ms cubic-bezier(0.2, 0.9, 0.2, 1) both; }
.nods-panel[data-nods-open] .gv { animation: gv-fade 200ms ease both; }
.nods-panel[data-nods-closing] .gv { animation: gv-leave 320ms ease both; }
.nods-panel[data-nods-closing] .gv-disc { animation: gv-back 240ms cubic-bezier(0.5, 0, 0.8, 0.4) both; }
.nods-panel[data-nods-closing] .gv-sleeve { animation: gv-gone 200ms ease 140ms both; }
@keyframes gv-out { from { translate: calc(var(--gv-out, 0.58) * -100%) 0; } }
/* The sleeve is never see-through: the record is behind it. */
@keyframes gv-in { from { translate: 0 0.6rem; } }
@keyframes gv-back { to { translate: calc(var(--gv-out, 0.58) * -100%) 0; } }
@keyframes gv-gone { to { translate: 0 0.4rem; } }
@keyframes gv-fade { from { opacity: 0; } }
@keyframes gv-leave { 0%, 60% { opacity: 1; } to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .gv *, .nods-panel[data-nods-open] .gv *, .nods-panel[data-nods-closing] .gv * { animation: none !important; }
}
@media print {
  .gv { height: auto; }
  .gv-disc { display: none; }
  .gv-sleeve { position: static; width: auto; background: #fff; color: #000; box-shadow: none; }
}

/* panel-listing — yours to edit.
 *
 * A sheet of continuous listing paper: bars of colour and of white, a hole
 * in each margin to every bar, a perforation inside the margin, and type
 * that keeps to the bars. Everything is a multiple of one bar.
 *
 *   --lp-bar                    the height of a bar, and so of a line
 *   --lp-paper, --lp-band       the white bar and the coloured one
 *   --lp-ink, --lp-accent       the type, and the tags and attribute names
 *   --lp-dim                    line numbers and comments
 *   --lp-mono, --lp-size        the face and its size
 *   --lp-name-size              the most the name may be
 *   --lp-w                      the width of the sheet
 */

.nods-panel:has(.lp) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 260ms; }
.nods-panel:has(.lp)[data-nods-closing] { opacity: 1; transform: none; }

/* The slot the paper comes out of: it is as big as the sheet and hides
 * whatever of the sheet has not been fed yet. The sheet lies a little off
 * the square, as a sheet does that has just come off a printer. */
.lp-slot { overflow: hidden; rotate: var(--lp-tilt, -1.2deg); transform-origin: 50% 100%; max-width: 100%; }

.lp {
  --_bar: var(--lp-bar, 1.5rem);
  --_edge: 1.6rem;
  --_ink: var(--lp-ink, var(--nods-ink, #111a12));
  --_dim: var(--lp-dim, var(--nods-muted, #526253));
  --_hole: radial-gradient(circle at 50% 50%, transparent 0.25rem, #000 0.29rem);
  box-sizing: border-box;
  container-type: inline-size;
  width: var(--lp-w, var(--nods-width, 25rem));
  max-width: 100%;
  padding: 0 var(--_edge);
  color: var(--_ink);
  background:
    /* A ring round each hole, so that it shows on the white bar as on the green. */
    radial-gradient(circle at 50% 50%, transparent 0.29rem, color-mix(in oklab, var(--_ink) 13%, transparent) 0.3rem 0.35rem, transparent 0.37rem) 0 0 / var(--_edge) var(--_bar) repeat-y,
    radial-gradient(circle at 50% 50%, transparent 0.29rem, color-mix(in oklab, var(--_ink) 13%, transparent) 0.3rem 0.35rem, transparent 0.37rem) 100% 0 / var(--_edge) var(--_bar) repeat-y,
    repeating-linear-gradient(to bottom,
    var(--lp-paper, var(--nods-ground, #f9f9f2)) 0 var(--_bar),
    var(--lp-band, #dfeeda) var(--_bar) calc(var(--_bar) * 2));
  font-family: var(--lp-mono, var(--nods-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace));
  font-size: var(--lp-size, 0.8125rem);
  line-height: var(--_bar);
  text-align: left;
  /* The holes are holes: the page shows through them. One column of them at
   * each edge, one to a bar. */
  -webkit-mask: var(--_hole) 0 0 / var(--_edge) var(--_bar) repeat-y, var(--_hole) 100% 0 / var(--_edge) var(--_bar) repeat-y, linear-gradient(#000 0 0) 50% 0 / calc(100% - var(--_edge) * 2) 100% no-repeat;
  mask: var(--_hole) 0 0 / var(--_edge) var(--_bar) repeat-y, var(--_hole) 100% 0 / var(--_edge) var(--_bar) repeat-y, linear-gradient(#000 0 0) 50% 0 / calc(100% - var(--_edge) * 2) 100% no-repeat;
}
.lp p, .lp ol { margin: 0; padding: 0; list-style: none; }

/* What the sheet is a listing of, and which page: the first line a printer
 * puts on every sheet. It and the lines under it sit between the two
 * perforations. */
.lp .lp-head, .lp .lp-rows { border-inline: 1px dashed color-mix(in oklab, var(--_ink) 26%, transparent); padding-inline: 0.7rem; }
.lp-head { display: flex; justify-content: space-between; gap: 1rem; color: var(--_dim); font-size: 0.6875rem; letter-spacing: 0.04em; }
.lp-head span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-head span:last-child { flex: none; }

/* On a narrow sheet the type is a size down, so a line still fits its bar. */
.lp-rows { font-size: clamp(0.6875rem, 3.75cqi, 0.8125rem); }
.lp-rows li { display: grid; grid-template-columns: 2.1em minmax(0, 1fr); height: var(--_bar); }
.lp-no { color: var(--_dim); font-size: 0.6875rem; font-variant-numeric: tabular-nums; }
.lp-line { padding-left: calc(var(--in, 0) * 1.2em); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-t, .lp-k { color: var(--lp-accent, var(--nods-accent, #17663a)); }
.lp-s { font-weight: 600; }
.lp-c { color: var(--_dim); }
.lp-link { overflow-wrap: anywhere; color: inherit; text-decoration: none; border-bottom: 1px solid color-mix(in oklch, currentColor 50%, transparent); }
.lp-link:hover { border-bottom-color: currentColor; }
.lp-link:focus-visible { outline: 2px solid var(--_ink); outline-offset: 2px; }

/* The name: two bars high, and the only large thing on the sheet. Sized so
 * that it fits the line it is on, whatever it is. */
.lp-rows li[data-big] { height: calc(var(--_bar) * 3); }
.lp-rows li[data-big] .lp-no { line-height: var(--_bar); }
.lp-name {
  display: block;
  margin-left: -0.04em;
  font-size: clamp(1.125rem, calc((100cqi - 5.4rem) / (var(--n, 12) * 0.62)), var(--lp-name-size, 3.5rem));
  font-weight: 800;
  line-height: calc(var(--_bar) * 3);
  letter-spacing: -0.02em;
  white-space: nowrap;
  /* Printed in dots, the way a matrix head builds a large letter. */
  -webkit-mask: radial-gradient(circle, #000 1.02px, transparent 1.22px) 0 0 / 2.5px 2.5px;
  mask: radial-gradient(circle, #000 1.02px, transparent 1.22px) 0 0 / 2.5px 2.5px;
}

.lp-name[data-plain] { font-size: inherit; line-height: var(--_bar); letter-spacing: 0; -webkit-mask: none; mask: none; }

/* The block left after the last character. */
.lp-cur { display: inline-block; width: 0.6em; height: 1.05em; margin-left: 0.4em; vertical-align: -0.18em; background: var(--_ink); animation: lp-blink 1.1s steps(1) infinite; }
@keyframes lp-blink { 50% { opacity: 0; } }

/* Printing. A line is not there, and then it is, with the ink still wet for
 * a moment; the next follows it at a printer's pace. */
/* Fed up out of the slot a bar at a time; and drawn back down to leave. */
.nods-panel[data-nods-open] .lp { animation: lp-feed 820ms steps(var(--rows, 14), jump-none) both; }
.nods-panel[data-nods-closing] .lp { animation: lp-draw 260ms steps(8) both; }
@keyframes lp-feed { from { transform: translateY(100%); } }
@keyframes lp-draw { to { transform: translateY(101%); } }

@media (prefers-reduced-motion: reduce) {
  .lp, .lp *, .nods-panel[data-nods-open] .lp, .nods-panel[data-nods-open] .lp *, .nods-panel[data-nods-closing] .lp { animation: none !important; }
  .lp-slot { rotate: none; }
}
@media (prefers-contrast: more) { .lp-no, .lp-c, .lp-head { color: var(--_ink); } .lp-link { border-bottom-color: currentColor; } }
@media print { .lp { background: #fff; -webkit-mask: none; mask: none; } .lp-cur { display: none; } }

/* panel-foil — yours to edit.
 *
 * A tall dark card with foil on it, which turns towards the pointer.
 *
 *   --fo-bg, --fo-ink            the card and its type
 *   --fo-foil                    the colours in the foil, as a conic gradient's stops
 *   --fo-tilt                    how far it turns, at most
 *   --fo-display, --fo-face, --fo-mono
 *   --fo-name-size               the most the name may be
 *   --fo-radius, --fo-w, --fo-h
 */

@property --fo-rx { syntax: "<angle>"; inherits: true; initial-value: 0deg; }
@property --fo-ry { syntax: "<angle>"; inherits: true; initial-value: 0deg; }
@property --fo-at { syntax: "<angle>"; inherits: true; initial-value: 0deg; }

.nods-panel:has(.fo) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 300ms; }
.nods-panel:has(.fo)[data-nods-closing] { opacity: 1; transform: none; }

.fo {
  --_t: var(--fo-tilt, 11deg);
  position: relative;
  box-sizing: border-box;
  width: var(--fo-w, var(--nods-width, 14.5rem));
  max-width: 100%;
  height: var(--fo-h, 20.5rem);
  perspective: 60rem;
  font-family: var(--fo-face, var(--nods-face, inherit));
  text-align: left;
}
.fo p { margin: 0; }

/* Nine places the pointer can be, three by three, lying under the card's
 * type and over nothing: they do not turn with the card, so the card cannot
 * turn itself out from under the pointer. Each sets where the card leans. */
.fo-zones { position: absolute; inset: -0.5rem; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); z-index: 1; }
.fo:has(.fo-zones i:nth-child(1):hover) { --fo-rx: var(--_t); --fo-ry: calc(var(--_t) * -1); --fo-at: -70deg; }
.fo:has(.fo-zones i:nth-child(2):hover) { --fo-rx: var(--_t); --fo-ry: 0deg; --fo-at: -20deg; }
.fo:has(.fo-zones i:nth-child(3):hover) { --fo-rx: var(--_t); --fo-ry: var(--_t); --fo-at: 30deg; }
.fo:has(.fo-zones i:nth-child(4):hover) { --fo-rx: 0deg; --fo-ry: calc(var(--_t) * -1); --fo-at: -110deg; }
.fo:has(.fo-zones i:nth-child(5):hover) { --fo-rx: 0deg; --fo-ry: 0deg; --fo-at: 0deg; }
.fo:has(.fo-zones i:nth-child(6):hover) { --fo-rx: 0deg; --fo-ry: var(--_t); --fo-at: 80deg; }
.fo:has(.fo-zones i:nth-child(7):hover) { --fo-rx: calc(var(--_t) * -1); --fo-ry: calc(var(--_t) * -1); --fo-at: -160deg; }
.fo:has(.fo-zones i:nth-child(8):hover) { --fo-rx: calc(var(--_t) * -1); --fo-ry: 0deg; --fo-at: 170deg; }
.fo:has(.fo-zones i:nth-child(9):hover) { --fo-rx: calc(var(--_t) * -1); --fo-ry: var(--_t); --fo-at: 130deg; }

.fo-card {
  --_bg: var(--fo-bg, var(--nods-ground, #0e0e12));
  --_ink: var(--fo-ink, var(--nods-ink, #f5f3ee));
  position: relative;
  z-index: 2;
  box-sizing: border-box;
  container-type: inline-size;
  height: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto auto;
  padding: var(--fo-pad, var(--nods-pad, 1.15rem));
  overflow: hidden;
  background: var(--_bg);
  color: var(--_ink);
  border-radius: var(--fo-radius, var(--nods-radius, 0.9rem));
  box-shadow: 0 1px 0 rgb(255 255 255 / 0.14) inset, 0 0.9rem 1.6rem -0.9rem rgb(0 0 0 / 0.55);
  /* The type lets the pointer through to the areas under it; the links take
   * it back for themselves. */
  pointer-events: none;
  transform: rotateX(var(--fo-rx)) rotateY(var(--fo-ry));
  transition: --fo-rx 220ms ease-out, --fo-ry 220ms ease-out, --fo-at 320ms ease-out;
  /* Left alone, it sways. */
  animation: fo-sway 7s ease-in-out infinite;
}
.fo-card a { pointer-events: auto; }
/* Under a pointer the sway stops and the pointer has it. */
.fo:has(.fo-zones i:hover) .fo-card { animation: none; }
@keyframes fo-sway {
  0%, 100% { --fo-rx: 3deg; --fo-ry: -7deg; --fo-at: -40deg; }
  50% { --fo-rx: -2deg; --fo-ry: 7deg; --fo-at: 50deg; }
}

/* The foil: a wheel of colour seen through a fine engraved pattern, turned
 * as the card is turned, and brightest where the light would be. */
.fo-foil {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 50% 26%, rgb(255 255 255 / 0.22), transparent 60%),
    conic-gradient(from var(--fo-at) at 50% 60%, var(--fo-foil, #ff5fa8, #ffd36b, #6bffd0, #6ba8ff, #c86bff, #ff5fa8));
  -webkit-mask:
    repeating-linear-gradient(115deg, #000 0 1px, transparent 1px 3px),
    repeating-linear-gradient(25deg, rgb(0 0 0 / 0.3) 0 1px, transparent 1px 7px);
  mask:
    repeating-linear-gradient(115deg, #000 0 1px, transparent 1px 3px),
    repeating-linear-gradient(25deg, rgb(0 0 0 / 0.3) 0 1px, transparent 1px 7px);
  opacity: 0.9;
}
/* The type is kept clear of the foil where it has to be read. */
.fo-card::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, color-mix(in oklab, var(--_bg) 78%, transparent) 0 14%, transparent 34% 52%, color-mix(in oklab, var(--_bg) 88%, transparent) 72%); }
.fo-card > p { position: relative; z-index: 1; }

.fo-top, .fo-page { font-family: var(--fo-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; letter-spacing: 0.06em; }
.fo-top { display: flex; flex-wrap: wrap; gap: 0.1rem 0; text-transform: uppercase; }
.fo-top span { overflow-wrap: anywhere; }
.fo-top span:not(:last-child)::after { content: "\00a0\00b7\00a0"; }

/* The name: a word to a line, as large as the card is wide. */
.fo-name {
  align-self: end;
  font-family: var(--fo-display, var(--nods-display, ui-serif, Georgia, "Times New Roman", serif));
  font-size: clamp(1.75rem, calc(190cqi / var(--n, 6)), var(--fo-name-size, 4.75rem));
  font-style: var(--fo-name-style, italic);
  font-weight: var(--fo-name-weight, 400);
  line-height: 0.9;
  letter-spacing: -0.02em;
  text-shadow: 0 1px 0 rgb(0 0 0 / 0.35);
}
.fo-name span { display: block; white-space: nowrap; }
.fo .fo-line { margin-top: 0.6rem; font-size: 0.875rem; line-height: 1.3; text-wrap: balance; }
.fo-links { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; gap: 0.3rem; margin-top: 0.9rem; padding-top: 0.75rem; border-top: 1px solid color-mix(in oklab, var(--_ink) 30%, transparent); }
.fo .fo-links { margin-top: 0.9rem; }
/* An address too long for the card is cut with an ellipsis. A name never is. */
.fo-site, .fo-page { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.fo-site { font-size: 0.875rem; font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.22em; padding-bottom: 0.15em; }
.fo-page:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.fo a:focus-visible { outline: 2px solid var(--_ink); outline-offset: 3px; border-radius: 2px; }

/* Turned over to arrive, and turned back over to leave. */
.nods-panel[data-nods-open] .fo { animation: fo-turn 760ms cubic-bezier(0.2, 0.85, 0.25, 1) both; }
.nods-panel[data-nods-closing] .fo { animation: fo-away 300ms cubic-bezier(0.5, 0, 0.8, 0.4) both; }
@keyframes fo-turn { from { transform: perspective(60rem) rotateY(-170deg) scale(0.86); opacity: 0; } 35% { opacity: 1; } }
@keyframes fo-away { to { transform: perspective(60rem) rotateY(110deg) scale(0.9); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .fo, .fo *, .nods-panel[data-nods-open] .fo, .nods-panel[data-nods-closing] .fo { animation: none !important; transition: none !important; }
  .fo-card { transform: none; }
}
@media (prefers-contrast: more) { .fo-foil { opacity: 0.35; } }
@media print { .fo-card { background: #fff; color: #000; box-shadow: none; transform: none; } .fo-foil, .fo-card::after { display: none; } }

/* panel-swatches — yours to edit.
 *
 * A deck of colour chips on a rivet, opened into a fan, with the maker's
 * cover in front of it. The card is the shape of the fan and has no ground.
 *
 *   --sw-w                      the width the fan is kept inside
 *   --sw-chip-w, --sw-chip-h    one chip
 *   --sw-spread                 the angle from the first chip to the last
 *   --sw-chip-radius
 *   --sw-cover-bg, --sw-cover-ink   the cover, which is the maker's
 *   --sw-cover-w, --sw-cover-h
 *   --sw-display, --sw-face, --sw-mono
 *   --sw-name-size
 */

.nods-panel:has(.sw) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 300ms; }
.nods-panel:has(.sw)[data-nods-closing] { opacity: 1; transform: none; }

.sw {
  --_cw: var(--sw-chip-w, 5.5rem);
  --_ch: var(--sw-chip-h, 17.25rem);
  /* How far up a chip the rivet goes through it. */
  --_pin: 0.95rem;
  /* The angle between two chips: the spread over the gaps, and never so wide
   * that two chips part company. */
  --_step: min(21deg, calc(var(--sw-spread, 76deg) / max(1, var(--k) - 1)));
  position: relative;
  box-sizing: border-box;
  width: var(--sw-w, var(--nods-width, 25rem));
  max-width: 100%;
  height: calc(var(--_ch) + 2.5rem);
  font-family: var(--sw-face, var(--nods-face, inherit));
  text-align: left;
}
.sw p { margin: 0; }

/* The rivet is a point at the middle of the foot. Every chip is hung on it
 * and turned about it. */
/* It is far enough up that the turned ends of the chips stay behind the cover. */
.sw-fan { position: absolute; left: 50%; bottom: 3.1rem; width: 0; height: 0; }
.sw-chip {
  position: absolute;
  left: calc(var(--_cw) / -2);
  bottom: calc(var(--_pin) * -1);
  box-sizing: border-box;
  width: var(--_cw);
  height: var(--_ch);
  padding: 0.6rem 0.55rem;
  background: var(--c);
  color: var(--on);
  border-radius: var(--sw-chip-radius, 0.55rem);
  /* The shadow each chip lays on the one under it. */
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1), -2px 0 4px -2px rgb(0 0 0 / 0.3);
  transform-origin: 50% calc(100% - var(--_pin));
  /* Turned to its place in the fan, and then drawn out along its own length
   * when it is under the pointer. */
  transform: rotate(calc(var(--at) * var(--_step))) translateY(var(--_pull, 0rem));
  transition: transform 200ms cubic-bezier(0.2, 0.9, 0.2, 1);
}
.sw-chip:hover { --_pull: -1.1rem; }
/* The value, at the far end of the chip, where it shows when the fan is open. */
/* On a tab of paper, as a chip has its number: any colour can be read on it. */
.sw-chip b { display: inline-block; padding: 0.22rem 0.32rem; background: #fbf9f3; color: #14171a; border-radius: 2px; font-family: var(--sw-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; font-weight: 500; line-height: 1; letter-spacing: 0.04em; }

/* The cover: shorter than the chips, so the one behind it shows its end over
 * the top, and upright, so it can be read. Its head is a block of the first
 * colour with the maker's name reversed out of it; under that, on the card's
 * own stock, what was made and where to go. The rivet goes through its foot,
 * and the second address is set under the rivet. */
.sw-cover {
  position: absolute;
  left: 50%;
  bottom: 0.4rem;
  translate: -50% 0;
  box-sizing: border-box;
  width: var(--sw-cover-w, 12rem);
  min-height: var(--sw-cover-h, 15rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(46%, auto) auto 1fr auto;
  justify-items: start;
  overflow: hidden;
  background: var(--sw-cover-bg, var(--nods-ground, #fbf9f3));
  color: var(--sw-cover-ink, var(--nods-ink, #14171a));
  border-radius: var(--sw-chip-radius, 0.55rem);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1), 0 2px 5px rgb(0 0 0 / 0.16);
}
.sw-head { justify-self: stretch; display: grid; grid-template-columns: minmax(0, 1fr); align-content: space-between; gap: 0.6rem; padding: 0.85rem 0.9rem 0.8rem; background: var(--sw-cover-accent, var(--c0, #14171a)); color: var(--sw-cover-on, var(--on0, #fff)); }
.sw-role { font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; }
.sw-name {
  font-family: var(--sw-display, var(--nods-display, ui-serif, Georgia, "Times New Roman", serif));
  font-size: var(--sw-name-size, 2.125rem);
  font-weight: var(--sw-name-weight, 400);
  line-height: 0.95;
  letter-spacing: -0.02em;
  overflow-wrap: break-word;
}
.sw-name[data-long] { font-size: 1.25rem; line-height: 1.05; }
.sw .sw-for { margin: 0.7rem 0.9rem 0; font-size: 0.75rem; line-height: 1.3; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.sw-for span { display: block; color: color-mix(in oklab, currentColor 68%, transparent); }
/* An address too long for the cover is cut with an ellipsis. A name never is. */
.sw-site, .sw-page { max-width: calc(100% - 1.8rem); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.sw-site { grid-row: 3; align-self: end; margin: 0 0.9rem 2.3rem; font-size: 0.75rem; font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.22em; padding-bottom: 0.15em; }
.sw-page { grid-row: 4; justify-self: center; max-width: calc(100% - 1rem); margin-bottom: 0.7rem; font-family: var(--sw-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; }
.sw-page:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.sw a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 2px; }

/* The rivet: an eyelet, on the point the chips turn about. */
.sw-pin { position: absolute; left: 50%; bottom: calc(2.7rem - 0.3rem); width: 0.6rem; height: 0.6rem; translate: -50% 0; border-radius: 50%; background: radial-gradient(circle, #fbf9f3 0 30%, #8d8778 34%); box-shadow: 0 1px 1px rgb(0 0 0 / 0.3); }

/* Opening: closed behind the cover, then each chip out to its place, the
 * outermost last, a little past and back. */
.nods-panel[data-nods-open] .sw-chip { animation: sw-open 820ms cubic-bezier(0.3, 1.45, 0.5, 1) both; animation-delay: calc(var(--j) * 55ms + 220ms); }
.nods-panel[data-nods-open] .sw-cover { animation: sw-cover 420ms cubic-bezier(0.2, 0.9, 0.2, 1) both; }
.nods-panel[data-nods-open] .sw { animation: sw-in 160ms ease both; }
@keyframes sw-in { from { opacity: 0; } }
@keyframes sw-open { from { transform: rotate(0deg); } }
@keyframes sw-cover { from { translate: -50% 0.75rem; } }

/* Closing: the fan is shut, and the deck is put away. */
.nods-panel[data-nods-closing] .sw-chip { animation: sw-shut 220ms cubic-bezier(0.5, 0, 0.8, 0.4) both; }
.nods-panel[data-nods-closing] .sw { animation: sw-away 160ms ease 160ms both; }
@keyframes sw-shut { to { transform: rotate(0deg); } }
@keyframes sw-away { to { opacity: 0; translate: 0 0.5rem; } }

@media (prefers-reduced-motion: reduce) {
  .sw, .sw *, .nods-panel[data-nods-open] .sw *, .nods-panel[data-nods-closing] .sw, .nods-panel[data-nods-closing] .sw * { animation: none !important; transition: none !important; }
}
@media print {
  .sw { height: auto; }
  .sw-fan, .sw-pin { display: none; }
  .sw-cover { position: static; translate: none; width: auto; height: auto; box-shadow: none; background: #fff; color: #000; }
}

/* panel-drafting — yours to edit.
 *
 * A working drawing, in the blue of a print: the ground is the blue and the
 * lines are the paper. Everything keeps to one module, the minor square of
 * the grid, and the heavier grid falls on every fifth.
 *
 *   --df-bg, --df-ink          the print's blue and its lines
 *   --df-grid                  the module: one minor square
 *   --df-mono                  the lettering
 *   --df-name-size             the most the name may be
 *   --df-name-weight
 *   --df-w, --df-h             the sheet
 */

.nods-panel:has(.df) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 260ms; }
.nods-panel:has(.df)[data-nods-closing] { opacity: 1; transform: none; }

.df {
  --_bg: var(--df-bg, var(--nods-ground, #103a8c));
  --_ink: var(--df-ink, var(--nods-ink, #eaf2ff));
  --_g: var(--df-grid, 8px);
  --_rule: color-mix(in oklab, var(--_ink) 62%, var(--_bg));
  position: relative;
  box-sizing: border-box;
  container-type: inline-size;
  width: var(--df-w, var(--nods-width, 25rem));
  max-width: 100%;
  min-height: var(--df-h, 18rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  /* The drawing, its title block and its links are one group, in the middle
   * of the sheet from top to bottom as well as from side to side. */
  grid-template-rows: auto auto auto;
  align-content: center;
  padding: calc(var(--_g) * 3);
  overflow: hidden;
  color: var(--_ink);
  background-color: var(--_bg);
  /* The grid's last line, on the two edges the pattern does not reach. */
  box-shadow: inset -1px -1px 0 color-mix(in oklab, var(--_ink) 13%, transparent);
  /* The grid, registered to the corner of the sheet: a faint line every
   * module and a firmer one every fifth. Drawn in the ink at low strength,
   * so a sheet in other colours carries its own grid. */
  background-image:
    linear-gradient(to right, color-mix(in oklab, var(--_ink) 13%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklab, var(--_ink) 13%, transparent) 1px, transparent 1px),
    linear-gradient(to right, color-mix(in oklab, var(--_ink) 5%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklab, var(--_ink) 5%, transparent) 1px, transparent 1px);
  background-size: calc(var(--_g) * 5) calc(var(--_g) * 5), calc(var(--_g) * 5) calc(var(--_g) * 5), var(--_g) var(--_g), var(--_g) var(--_g);
  font-family: var(--df-mono, var(--nods-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace));
  font-size: 0.8125rem;
  line-height: 1.3;
  /* Everything on the sheet is set on its centre line. */
  text-align: center;
}
.df p, .df dl, .df dd { margin: 0; }
/* The frame a sheet is ruled with, one module in from its edge. */
.df::before { content: ""; position: absolute; inset: var(--_g); border: 1px solid var(--_rule); pointer-events: none; }

/* The drawing. One row, in the middle of the sheet: the name standing on the
 * datum, between the datum's two targets. The row's type size is the name's,
 * so every measure in it is in the name's own ems. */
.df-field { display: grid; align-content: center; padding: calc(var(--_g) * 2.5) 0 calc(var(--_g) * 2.5); }
.df-row {
  position: relative;
  /* Where the letters' feet are, above the foot of their line. */
  --_base: var(--df-baseline, 0.135em);
  display: grid; grid-template-columns: auto auto auto; justify-content: center; align-items: baseline; column-gap: max(0.26em, 0.5rem);
  /* The name, a target each side of it and the two gaps between have to fit the sheet. */
  font-size: clamp(1.125rem, calc((100cqi - 3.6rem) / (var(--n, 12) * 0.6 + 1.4)), var(--df-name-size, 3.25rem));
  line-height: 1;
}
/* The datum: a broken line the width of the sheet, under the name's feet. */
.df-row::after { content: ""; position: absolute; left: -100vw; right: -100vw; bottom: var(--_base); border-top: 1px dashed var(--_rule); transform-origin: 30% 50%; }
/* The two lines over it: the height of the capitals, and of the small
 * letters. Finer than the datum. */
.df-guide { position: absolute; left: -100vw; right: -100vw; border-top: 1px solid color-mix(in oklab, var(--_ink) 46%, transparent); font-style: normal; }
.df-guide[data-at="cap"] { bottom: calc(var(--_base) + 0.7em); }
.df-guide[data-at="x"] { bottom: calc(var(--_base) + 0.53em); }
/* Its targets, one at each end of the name: a circle in quarters, two of them filled. */
.df-target { align-self: end; margin-bottom: calc(var(--_base) - max(0.19em, 0.4375rem)); /* Never smaller than can be read as a target, under a long name set small. */
  width: max(0.38em, 0.875rem); height: max(0.38em, 0.875rem); border-radius: 50%; box-shadow: 0 0 0 1px var(--_ink); background: conic-gradient(var(--_ink) 0 25%, transparent 0 50%, var(--_ink) 0 75%, transparent 0); position: relative; z-index: 1; }
.df-name {
  position: relative;
  z-index: 1;
  font-weight: var(--df-name-weight, 500);
  letter-spacing: 0;
  /* Inked in: a name is for reading. It is an outline only while it is
   * being drawn. */
  color: var(--_ink);
}

/* The dimension: a line over the name with a stroke across each end, and
 * what the maker is, in a word, set on a gap in it. */
/* A name of two letters is still wide enough to carry its dimension. */
.df-name { min-width: 0; }
.df-name > span { display: block; white-space: nowrap; }
.df-name > span + span { margin-top: 0.12em; }
.df-dim { position: absolute; display: grid; place-items: center; font-style: normal; -webkit-text-stroke: 0; color: var(--_ink); }
.df-dim::before { content: ""; position: absolute; inset: 0; background:
  linear-gradient(var(--_ink) 0 0) 50% 50% / 100% 1px no-repeat; }
.df-dim b { position: relative; padding: 0 0.6em; background: var(--_bg); font-size: 0.6875rem; font-weight: 400; line-height: 1; letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; }
/* As wide as the name, and wider where the name is shorter than the word
 * the line carries: a name of two letters still has its line each side. */
.df-wide { left: 50%; translate: -50% 0; box-sizing: border-box; min-width: 100%; width: max-content; padding-inline: 1.5rem; bottom: calc(100% + 0.16em); height: 0.75rem; }
/* The strokes at the ends, at forty-five degrees. */
.df-wide::after { content: ""; position: absolute; inset: 0; background:
  linear-gradient(135deg, transparent calc(50% - 0.6px), var(--_ink) calc(50% - 0.6px) calc(50% + 0.6px), transparent calc(50% + 0.6px)) 0 50% / 0.5rem 0.5rem no-repeat,
  linear-gradient(135deg, transparent calc(50% - 0.6px), var(--_ink) calc(50% - 0.6px) calc(50% + 0.6px), transparent calc(50% + 0.6px)) 100% 50% / 0.5rem 0.5rem no-repeat;
  translate: 0 0; margin-inline: -0.25rem; }

/* The title block: boxes ruled across, a small label over what it labels. */
.df-block { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.8fr) minmax(0, 1.1fr); border: 1px solid var(--_rule); background: var(--_bg); position: relative; }
/* On a narrow sheet the project has the width to itself and the other two
 * boxes share the row under it. */
@container (max-width: 19rem) {
  .df-block { grid-template-columns: 1fr 1fr; }
  .df-block .df-cell:first-child { grid-column: 1 / -1; border-right: 0; border-bottom: 1px solid var(--_rule); }
  .df-block .df-cell:nth-child(3n) { border-right: 1px solid var(--_rule); }
  .df-block .df-cell:nth-child(2n + 1), .df-block .df-cell:last-child { border-right: 0; }
  .df-block .df-cell:nth-child(n + 4) { border-top: 1px solid var(--_rule); }
}
.df-cell { min-width: 0; padding: 0.4rem 0.6rem 0.45rem; border-right: 1px solid var(--_rule); }
.df-cell:nth-child(3n), .df-cell:last-child { border-right: 0; }
/* A last box alone on its row, or one short of it, is given the rest. */
.df-cell:last-child:nth-child(3n + 1) { grid-column: 1 / -1; }
.df-cell:last-child:nth-child(3n + 2) { grid-column: span 2; }
.df-cell:nth-child(n + 4) { border-top: 1px solid var(--_rule); }
.df-cell dt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.6875rem; letter-spacing: 0.08em; text-transform: uppercase; color: color-mix(in oklab, var(--_ink) 78%, var(--_bg)); }
/* A name in a box is never cut: it takes a second line. */
.df-cell dd { overflow-wrap: anywhere; hyphens: auto; }

.df-links { position: relative; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.3rem 1.5rem; margin-top: calc(var(--_g) * 1.5); }
.df .df-links { margin-top: calc(var(--_g) * 1.5); }
/* An address too long for the sheet is cut with an ellipsis. A name never is. */
.df-link { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; border-bottom: 1px solid color-mix(in oklab, var(--_ink) 55%, transparent); }
.df-link::after { content: "\00a0\2197"; }
.df-link:hover { border-bottom-color: currentColor; }
.df-link:focus-visible { outline: 2px solid var(--_ink); outline-offset: 3px; }

/* Drawn while it is watched: the datum ruled from the left, the name plotted
 * along it, the dimension struck, the block filled in. */
.nods-panel[data-nods-open] .df-row::after { animation: df-rule 520ms cubic-bezier(0.3, 0, 0.2, 1) 80ms both; }
.nods-panel[data-nods-open] .df-guide { animation: df-guide 520ms cubic-bezier(0.3, 0, 0.2, 1) 160ms both; }
.nods-panel[data-nods-open] .df-guide[data-at="x"] { animation-delay: 240ms; }
.nods-panel[data-nods-open] .df-target { animation: df-pop 300ms ease 80ms both; }
.nods-panel[data-nods-open] .df-name { animation: df-plot 700ms steps(var(--n, 12), jump-none) 380ms both, df-ink 380ms ease 1180ms both; }
.nods-panel[data-nods-open] .df-dim { animation: df-strike 380ms ease 1000ms both; }
.nods-panel[data-nods-open] :is(.df-block, .df-links) { animation: df-fill 360ms ease 900ms both; }
/* The sheet is unrolled from the left, as it is rolled up to leave. */
.nods-panel[data-nods-open] .df { animation: df-unroll 320ms cubic-bezier(0.2, 0.9, 0.2, 1) both; }
@keyframes df-unroll { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes df-rule { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
/* The same, with room left over the line for what is written on it. */
@keyframes df-guide { from { clip-path: inset(-2em 100% -2em 0); } to { clip-path: inset(-2em 0 -2em 0); } }
@keyframes df-pop { from { scale: 0; } }
/* Room is left each side for a dimension that is wider than a short name. */
@keyframes df-plot { from { clip-path: inset(-1em 100% -1em -4rem); } to { clip-path: inset(-1em -4rem -1em -4rem); } }
@keyframes df-strike { from { opacity: 0; clip-path: inset(0 50% 0 50%); } to { opacity: 1; clip-path: inset(-1em); } }
@keyframes df-fill { from { opacity: 0; } }
@keyframes df-ink { from { color: transparent; -webkit-text-stroke: 1.25px var(--_ink); } to { -webkit-text-stroke: 0 var(--_ink); } }

/* Leaving: the sheet is rolled up from the right. */
.nods-panel[data-nods-closing] .df { animation: df-roll 260ms cubic-bezier(0.5, 0, 0.8, 0.4) both; }
@keyframes df-roll { to { clip-path: inset(0 100% 0 0); } }

@media (prefers-reduced-motion: reduce) {
  .df, .df *, .df *::after, .nods-panel[data-nods-open] .df *, .nods-panel[data-nods-open] .df *::after, .nods-panel[data-nods-closing] .df { animation: none !important; }
}
@media (prefers-contrast: more) { .df-cell dt { color: var(--_ink); } }
@media print {
  .df { background: #fff; color: #000; --_ink: #000; --_bg: #fff; }
}

/* panel-loop — yours to edit.
 *
 * The maker's name with a wave going through it, in a capsule.
 *
 *   --lo-bg, --lo-ink            the capsule and the type
 *   --lo-loop                    how long the wave takes to cross the name
 *   --lo-travel                  how far a letter rises
 *   --lo-thin, --lo-thick        the weights the wave runs between
 *   --lo-display, --lo-face, --lo-mono   the name wants a face of one width
 *   --lo-name-size               the most the name may be
 *   --lo-radius, --lo-w, --lo-h
 */

.nods-panel:has(.lo) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 260ms; }
.nods-panel:has(.lo)[data-nods-closing] { opacity: 1; transform: none; }

.lo {
  --_bg: var(--lo-bg, var(--nods-ground, #3b1ee0));
  --_ink: var(--lo-ink, var(--nods-ink, #fff));
  --_t: var(--lo-loop, 2.2s);
  position: relative;
  box-sizing: border-box;
  container-type: inline-size;
  width: var(--lo-w, var(--nods-width, 25rem));
  max-width: 100%;
  min-height: var(--lo-h, 10.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  justify-items: center;
  padding: 1.15rem 2.5rem 1.2rem;
  background: var(--_bg);
  color: var(--_ink);
  border-radius: var(--lo-radius, var(--nods-radius, 5.25rem));
  font-family: var(--lo-face, var(--nods-face, inherit));
  font-size: 0.8125rem;
  line-height: 1.3;
  text-align: center;
}
.lo p { margin: 0; }
.lo-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.lo-top, .lo-page { font-family: var(--lo-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; letter-spacing: 0.06em; }
.lo-top { display: flex; flex-wrap: wrap; justify-content: center; max-width: calc(100% - 2rem); text-transform: uppercase; }
.lo-top span { white-space: nowrap; }
.lo-top span:not(:last-child)::after { content: "\00a0\00b7\00a0"; }
/* Too long for one line: set without the points, which would be left hanging. */
.lo-top[data-long] { gap: 0 0.9em; }
.lo-top[data-long] span { white-space: normal; }
.lo-top[data-long] span::after { content: none; }

/* The name: one letter to a column, the whole width of the capsule. */
.lo-name {
  align-self: center; width: 100%;
  font-family: var(--lo-display, var(--nods-display, ui-monospace, SFMono-Regular, Menlo, monospace));
  font-size: clamp(1.25rem, calc((100cqi - 5rem) / var(--n, 8) * 1.5), var(--lo-name-size, 4.25rem));
  font-weight: 500;
  /* The weights in between are the face's own, never a smeared bold. */
  font-synthesis: none;
  line-height: 1.1;
  letter-spacing: 0;
  padding: 0.1em 0;
}
.lo-rows { display: grid; }
/* A column is two thirds of an em: at the fitted size the longest row fills
 * the capsule, and a short name stands together in the middle of it. */
.lo-set { display: grid; grid-template-columns: repeat(var(--cols, var(--n, 8)), minmax(0, 0.667em)); justify-content: center; }
.lo-l { display: block; justify-self: center; }

/* One letter's turn. Each starts later than the one before by its share of
 * the loop, so the crest travels the name from its first letter to its last. */
.lo-l {
  animation: lo-wave var(--_t) cubic-bezier(0.45, 0, 0.55, 1) infinite;
  animation-delay: calc((var(--i) + 0.5) / var(--n, 8) * var(--_t) - var(--_t));
}
@keyframes lo-wave {
  0%, 100% { transform: translateY(calc(var(--lo-travel, 0.14em) * -1)); font-variation-settings: "wght" var(--lo-thick, 800); }
  50% { transform: translateY(var(--lo-travel, 0.14em)); font-variation-settings: "wght" var(--lo-thin, 200); }
}

.lo-links { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 0.2rem 1.1rem; max-width: 100%; }
/* An address too long for the capsule is cut with an ellipsis. A name never is. */
.lo-site, .lo-page { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.lo-site { font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.22em; padding-bottom: 0.15em; }
.lo-page:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.lo a:focus-visible { outline: 2px solid var(--_ink); outline-offset: 3px; border-radius: 2px; }

/* From a line, and back to one. */
.nods-panel[data-nods-open] .lo { animation: lo-swell 560ms cubic-bezier(0.3, 1.5, 0.5, 1) both; }
.nods-panel[data-nods-open] .lo > * { animation: lo-in 300ms ease 260ms both; }
.nods-panel[data-nods-closing] .lo { animation: lo-flat 260ms cubic-bezier(0.5, 0, 0.8, 0.4) both; }
.nods-panel[data-nods-closing] .lo > * { animation: lo-out 120ms ease both; }
@keyframes lo-swell { from { transform: scaleY(0.03); } }
@keyframes lo-in { from { opacity: 0; } }
@keyframes lo-flat { to { transform: scaleY(0.03); opacity: 0; } }
@keyframes lo-out { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .lo, .lo *, .nods-panel[data-nods-open] .lo, .nods-panel[data-nods-open] .lo *, .nods-panel[data-nods-closing] .lo, .nods-panel[data-nods-closing] .lo * { animation: none !important; }
}
@media print { .lo { background: #fff; color: #000; } }

/* panel-cast — yours to edit.
 *
 * Everybody who made a site, each on a card of their own, laid one on the
 * next and held by a band that names the project.
 *
 *   --ct-bg, --ct-ink          the band, and the two colours the cards take
 *                              in turn when a maker is given none
 *   --ct-step                  how far each card stands in from the last
 *   --ct-display, --ct-face, --ct-mono
 *   --ct-name-size             the most a name may be
 *   --ct-radius, --ct-w, --ct-h
 *
 * Each card says whose it is, `data-maker="pocket-monday"`, so one maker can
 * be given their own type: `.ct-card[data-maker="pocket-monday"] .ct-who { … }`.
 *
 * One maker's card and the type on it are `--ct-tint` and `--ct-on`, which the
 * template writes on that card from its `tints` option.
 */

.nods-panel:has(.ct) { width: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; --nods-exit: 220ms; }
.nods-panel:has(.ct)[data-nods-closing] { opacity: 1; transform: none; }

.ct {
  --_bg: var(--ct-bg, var(--nods-ground, #0b0b0c));
  --_ink: var(--ct-ink, var(--nods-ink, #f6f4ee));
  /* The fewer the makers, the further each card stands in from the last. */
  --_dx: var(--ct-step, clamp(0.875rem, calc(4.5rem / var(--rows, 2)), 2.25rem));
  /* The band is wider than the cards it holds, by this much each side. */
  --_out: 0.5rem;
  box-sizing: border-box;
  container-type: inline-size;
  width: var(--ct-w, var(--nods-width, 25rem));
  max-width: 100%;
  min-height: var(--ct-h, 0);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  padding-inline: var(--_out);
  font-size: 0.875rem; line-height: 1.3; font-family: var(--ct-face, var(--nods-face, inherit));
  text-align: left;
}
.ct p, .ct ol { margin: 0; padding: 0; list-style: none; }

/* The cards. Each is as tall as what is written on it, and goes on under
 * the ones laid over it as far as the band, where it is cut off: what shows
 * of a card is its head, with the role and the name on it. */
.ct .ct-deck { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; overflow: hidden; padding-bottom: 2.6rem; }
.ct-card {
  position: relative; z-index: calc(var(--i, 0) + 1);
  box-sizing: border-box;
  width: calc(100% - (var(--rows, 2) - 1) * var(--_dx));
  margin-left: calc(var(--i, 0) * var(--_dx));
  display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(0.2rem, calc(1rem / var(--rows, 2)), 0.45rem);
  padding: clamp(0.5rem, calc(2rem / var(--rows, 2)), 0.95rem) 1rem clamp(0.55rem, calc(2.2rem / var(--rows, 2)), 1.05rem);
  background: var(--ct-tint, var(--_c));
  color: var(--ct-on, var(--_o));
  border-radius: var(--ct-radius, var(--nods-radius, 0)) var(--ct-radius, var(--nods-radius, 0)) 0 0;
  transition: translate 240ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* A maker who is given no colour takes one of the card's two in turn. The
 * card in front is always the light one, so the band reads against it. */
.ct-card:nth-last-child(odd) { --_c: var(--_ink); --_o: var(--_bg); }
.ct-card:nth-last-child(even) { --_c: color-mix(in oklab, var(--_bg) 86%, var(--_ink)); --_o: var(--_ink); }
/* The rest of the card, under the ones laid on it. */
.ct-card::after { content: ""; position: absolute; inset: 100% 0 auto; height: 60rem; background: inherit; }
/* A line where one card lies on another, for two that are near in colour. */
.ct-card + .ct-card { box-shadow: 0 -1px 0 color-mix(in oklab, currentColor 14%, transparent), -1px 0 0 color-mix(in oklab, currentColor 14%, transparent); }
.ct-card + .ct-card::after { box-shadow: -1px 0 0 color-mix(in oklab, currentColor 14%, transparent); }

.ct-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.ct-role, .ct-host, .ct-band { font-family: var(--ct-mono, var(--nods-mono, ui-monospace, SFMono-Regular, Menlo, monospace)); font-size: 0.6875rem; letter-spacing: 0.08em; }
.ct-role { flex: none; text-transform: uppercase; }
.ct-role, .ct-host { color: color-mix(in oklab, currentColor 68%, transparent); }
/* An address too long for the card is cut with an ellipsis. A name never is. */
.ct-host { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0.02em; text-decoration: none; }
a.ct-host::after { content: "\00a0\2197"; }
a.ct-host:hover { color: inherit; }

.ct-name { min-width: 0; }
.ct-who, .ct-mark {
  font-family: var(--ct-display, var(--nods-display, ui-serif, Georgia, "Times New Roman", serif));
  /* As large as the number of makers allows, and fitted to the card on one
   * line. A name too long for that at the smallest size takes a second. */
  font-size: clamp(1.0625rem, min(calc(5.4rem / var(--rows, 2) + 0.2rem), calc((100cqi - 3rem - (var(--rows, 2) - 1) * var(--_dx)) / (var(--n, 8) * 0.52))), var(--ct-name-size, 2.375rem));
  line-height: 1.05;
  letter-spacing: -0.015em;
}
.ct-who { color: inherit; text-decoration: none; overflow-wrap: anywhere; }
.ct-mark { display: inline-block; max-width: 100%; }
.ct .ct-mark .ct-who { font-size: 1em; }
a.ct-who { background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size 240ms cubic-bezier(0.16, 1, 0.3, 1); }
a.ct-who:hover, a.ct-who:focus-visible { background-size: 100% 1px; }
/* A mark is read in its card's own two colours: the highlighter is the
 * card's ink with the name in the card's colour, whatever they are. */
.ct .nods-as-marker { --nods-mark: var(--ct-on, var(--_o)); }
.ct .nods-as-marker .ct-who { color: var(--ct-tint, var(--_c)); background-size: 100% 100%; }
/* A highlighter stands clear of the role over it. */
.ct-name:has(.nods-as-marker) { padding-top: 0.3rem; }
.ct .nods-as-code .ct-who { display: inline-block; font-size: 0.74em; letter-spacing: 0; }

/* The band: round all of them, a little wider than they are, with the
 * project on it and the way to its page. */
.ct-band {
  position: relative; z-index: 99;
  /* A project with a long name and a long address take a line each. */
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem 1.25rem;
  margin: -1.45rem calc(-1 * var(--_out)) 0;
  padding: 0.8rem calc(1rem + var(--_out));
  background: var(--_bg); color: var(--_ink);
  /* A line over it, for a card as dark as it is. */
  box-shadow: 0 -1px 0 color-mix(in oklab, var(--_ink) 24%, var(--_bg));
}
.ct-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.7rem; min-width: 0; text-transform: uppercase; }
.ct-year { color: color-mix(in oklab, currentColor 62%, transparent); }
.ct-page { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; letter-spacing: 0.02em; border-bottom: 1px solid color-mix(in oklab, currentColor 50%, transparent); }
.ct-page::after { content: "\00a0\2197"; }
.ct-page:hover { border-bottom-color: currentColor; }
.ct a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 2px; }
/* On a narrow card the page has a line to itself under the project. */
@container (max-width: 19rem) { .ct-band { flex-direction: column; align-items: flex-start; } }

/* A pointer on a card draws it out a little. */
@media (hover: hover) { .ct-card:hover { translate: 0 -0.2rem; } }

/* Dealt: each card up into its place, one after the other, and then the
 * band round them. */
.nods-panel[data-nods-open] .ct-card { animation: ct-deal 560ms cubic-bezier(0.2, 0.85, 0.25, 1) both; animation-delay: calc(var(--i, 0) * 120ms + 60ms); }
.nods-panel[data-nods-open] .ct-band { animation: ct-band 420ms cubic-bezier(0.2, 0.85, 0.25, 1) both; animation-delay: calc(var(--rows, 2) * 120ms + 160ms); }
@keyframes ct-deal { from { transform: translateY(18rem); } }
@keyframes ct-band { from { clip-path: inset(0 50% 0 50%); } to { clip-path: inset(0 0 0 0); } }
/* The marks arrive as their makers do: the highlighter is drawn across its
 * name once the card has landed, and the element is typed out before its
 * caret settles. */
.nods-panel[data-nods-open] .ct .nods-as-marker .nods-name { animation: ct-swipe 420ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--i, 0) * 120ms + 520ms) both; }
.nods-panel[data-nods-open] .ct .nods-as-code .nods-name { animation: ct-type 520ms steps(14, jump-none) calc(var(--i, 0) * 120ms + 560ms) both, nods-caret 1s steps(1) 1300ms infinite; }
@keyframes ct-swipe { from { background-size: 0 100%; color: inherit; } }
@keyframes ct-type { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 -0.4em 0 0); } }
.nods-panel[data-nods-closing] .ct { animation: ct-out 220ms ease both; }
@keyframes ct-out { to { opacity: 0; transform: translateY(0.5rem); } }

@media (prefers-reduced-motion: reduce) {
  .ct, .ct *, .nods-panel[data-nods-open] .ct *, .nods-panel[data-nods-closing] .ct { animation: none !important; transition: none !important; }
}
@media (prefers-contrast: more) { .ct-role, .ct-host, .ct-year { color: inherit; } }
@media print { .ct { --_bg: #000; --_ink: #fff; } .ct-card { border: 1px solid #000; } }
