/* @importはpeitho.css(css/*.cssをファイル名順に連結)の先頭に来ないと無効。
   このファイル名はcss/内で必ず最初にソートされるよう00-を維持すること。 */
@import url("fonts/noto-sans-jp/index.css");
@import url("fonts/noto-serif-jp/index.css");
@import url("fonts/noto-sans/index.css");
@import url("fonts/noto-serif/index.css");
@import url("fonts/m-plus-1-code/index.css");
@import url("fonts/space-grotesk/index.css");
@import url("fonts/inter/index.css");
@import url("fonts/jetbrains-mono/index.css");

/* Perl.org design system: Lato at 100/300/400/700/900 */
@import url("https://fonts.googleapis.com/css2?family=Lato:wght@100;300;400;700;900&display=swap");

/* Perl's own palette, sampled from perl.org: the header blue #003555 for the dark
   slides and the camel mint #61c5ba as their accent, with a deeper Perl blue
   carrying text on the light ground. Light ground because this deck is mostly
   screenshots of white web pages; cover, profile and year slides sit on
   --bg-dark so the opening reads as one dark block and the first light slide is
   the first record. Swap --bg-dark / --fg-on-dark to reskin those together. */

/* Tokens live on .peitho-slide, not :root — the preview shell mounts
   slides inside a shadow root, where a :root rule never matches and
   every var() would fall back to nothing (invisible text). */
.peitho-slide {
  --slate-50: #f8f9fa;
  --slate-100: #f4f5f5;
  --slate-200: #e9ecef;
  --slate-300: #d9dbdc;
  --slate-400: #a4a9ac;
  --slate-500: #7c8487;
  --slate-600: #636a6d;
  --slate-700: #4b5052;
  --slate-800: #343a40;
  --slate-900: #212529;
  --gold-400: #0073a1;
  --gold-600: #005c81;
  --gold-700: #003555;
  --cyan-300: #8fdcd3;
  --cyan-400: #61c5ba;
  --cyan-600: #55a89f;
  --cyan-700: #3f7f78;

  --bg: #ffffff;
  --bg-panel: #f4f5f5;
  --fg1: #212529;
  --fg2: #212529;
  --fg3: #4b5052;
  --fg4: #636a6d;
  --border-strong: #d9dbdc;
  --accent: #0073a1;
  --accent-high: #003555;
  --link: #0073a1;
  --bg-dark: #003555;
  --fg-on-dark: #ffffff;

  /* Perl.org's own roles, kept under their own names so the intent survives. */
  --perl-blue: #0073a1;
  --perl-blue-dark: #003555;
  --perl-blue-shade: #005c81;
  --perl-teal: #61c5ba;
  --perl-amber: #f0ad4e;
  --gradient-nav: linear-gradient(#00456e, #003555);
  --gradient-band: linear-gradient(#f4f5f5, #d9dbdc);

  --font-display: "Lato", "Noto Sans JP Variable", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-sans: "Lato", "Noto Sans JP Variable", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono Variable", "Noto Sans JP Variable", ui-monospace, "SF Mono", Menlo, monospace;
}

.peitho-slide {
  width: 1280px;
  height: 720px;
  box-sizing: border-box;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 64px 88px;
  background: var(--bg);
  color: var(--fg2);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

/* Single upstream rule so every code-ish element gets the webfont — slot-scoped
   rules kept leaking inline <code> in other slots to the browser default (OS fonts).
   Noto Sans JP is second because Latin mono subsets claim some codepoints
   (e.g. U+2192 arrows) without containing the glyph, so a webfont catches them
   for environment-independent PDFs. */
pre,
code,
kbd,
samp {
  font-family: var(--font-mono);
}

.crn h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 44px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--fg1);
  line-break: strict;
  word-break: auto-phrase;
}

.crn h1 .slot-title code {
  font-size: 0.92em;
}

/* --- cover --- */

/* The profile slide shares the cover's ground so the opening
   (cover → who → first year) reads as one dark block and the first light slide is
   the first record. */
.crn-cover,
.crn-profile {
  justify-content: center;
  background: var(--bg-dark);
  color: var(--fg-on-dark);
}

.crn-cover h1,
.crn-profile h1 {
  color: var(--slate-50);
}

.crn-cover .crn-inner::before {
  content: "ANOTHER TALK";
  display: block;
  margin-bottom: 26px;
  font-family: var(--font-sans);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--gold-400);
}

.crn-cover h1 {
  font-size: 64px;
}

/* Event meta mirrors the eyebrow: same size and tracking, cyan against
   its gold, with the date stepped back to fg4. */
.cover-meta {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 44px 0 0;
  font-family: var(--font-sans);
  font-size: 28px;
  --peitho-lint-min-font-size: 28px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--cyan-400);
}

.cover-meta-sub {
  margin-left: 16px;
  font-size: 22px;
  --peitho-lint-min-font-size: 22px;
  font-weight: 400;
  color: var(--slate-400);
}

.cover-meta-date {
  font-size: 22px;
  --peitho-lint-min-font-size: 22px;
  letter-spacing: 0.12em;
  color: var(--slate-500);
}

/* Statement slides: same rules as the cover, but on the dark ground the year
   slides use, so "dark = structure/claim, white = other people's records". */
.crn-statement .crn-inner::before {
  content: none;
}

.crn-statement h1 {
  font-size: 80px;
}

.crn-statement .statement-note,
.crn-statement .statement-note .slot-body p {
  color: var(--slate-400);
}

.crn-statement .statement-note a {
  color: var(--slate-300);
}

.crn-statement .statement-note:has(a) {
  border-top-color: var(--slate-700);
}

.crn-statement .statement-note .slot-body p:has(a)::before {
  color: var(--gold-400);
  border-color: var(--gold-400);
}

/* --- profile --- */

.crn-profile {
  align-items: center;
  justify-content: center;
  text-align: center;
}

.profile-photo {
  margin: 0 0 20px;
}

.profile-photo img {
  width: 170px;
  height: 170px;
  border-radius: 50%;
  border: 1px solid var(--slate-700);
  object-fit: cover;
}

.crn-profile h1 {
  font-size: 54px;
}

.profile-body {
  margin-top: 28px;
}

.crn-profile .slot-body {
  font-size: 38px;
  line-height: 1.5;
  color: var(--slate-300);
}

.crn-profile .slot-body p {
  max-width: none;
  margin: 0 0 10px;
}

.crn-profile .slot-body a {
  color: var(--cyan-400);
}

/* --- footnotes --- */

.crn-footnotes {
  min-width: 0;
  margin-top: auto;
}

.crn-footnotes:empty {
  display: none;
}

.peitho-footnotes {
  padding-top: 14px;
  border-top: 1px solid var(--border-strong);
  font-size: 17px;
  --peitho-lint-min-font-size: 17px;
  line-height: 1.5;
  color: var(--fg3);
}

.peitho-footnotes ol {
  margin: 0;
  padding-left: 1.4em;
}

.peitho-footnotes p {
  margin: 0;
}

.peitho-footnotes a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* --- shared body --- */

.crn-body {
  margin-top: 34px;
}

.slot-body {
  font-size: 32px;
  line-height: 1.75;
  color: var(--fg2);
  line-break: strict;
  word-break: auto-phrase;
}

.slot-body p {
  margin: 0 0 18px;
}

.slot-body a {
  color: var(--link);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.slot-body strong {
  color: var(--fg1);
}

.slot-body code {
  font-size: 1em;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--bg-panel);
  color: var(--accent-high);
}

.slot-body ul {
  margin: 0;
  padding-left: 1.1em;
}

.slot-body li {
  margin-bottom: 12px;
}

.slot-body li::marker {
  color: var(--accent);
}

/* --- shot: one record per slide. Title, the screenshot, one-line caption. --- */

.crn-shot h1 {
  flex: none;
  font-size: 34px;
}

/* The figure takes whatever height is left. The image shrinks to fit that box
   (max-width/max-height resolve because the slide height is fixed) so the border
   hugs the picture instead of the letterbox. */
.shot-frame {
  flex: 1;
  min-height: 0;
  margin: 26px 0 0;
}

.shot-frame .slot-shot {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.shot-frame img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.shot-frame img {
  border: 1px solid var(--slate-300);
}

.shot-caption {
  flex: none;
  margin-top: 12px;
}

.crn-shot .slot-body {
  font-size: 24px;
  --peitho-lint-min-font-size: 24px;
  line-height: 1.5;
  color: var(--fg3);
}

.crn-shot .slot-body p {
  margin: 0;
}

.crn-shot .slot-body a {
  color: var(--fg3);
  text-decoration-color: var(--slate-300, #cbd5e1);
}

/* Optional small source note under a statement title (closing slide). */
.statement-note {
  margin-top: 50px;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  line-height: 1.6;
  color: var(--fg4);
}

.statement-note .slot-body p {
  margin: 0;
  font-size: 22px;
  --peitho-lint-min-font-size: 22px;
}

/* count: "ほかにも N件" after a representative record. Same header and source line as
   shot, so it reads as the next page of the record before it; the number is
   the only large thing on the slide. */
.count-main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.count-main .slot-count p {
  margin: 0;
  font-size: 44px;
  --peitho-lint-min-font-size: 44px;
  line-height: 1.3;
  color: var(--slate-700);
}

.count-main .slot-count p + p {
  margin-top: 8px;
  font-size: 64px;
  --peitho-lint-min-font-size: 64px;
  color: var(--perl-blue-dark);
}

.count-main .slot-count strong {
  margin-right: 16px;
  font-family: var(--font-display);
  font-size: 200px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.04em;
}

.crn-count[data-empty-slots~="body"] .shot-caption {
  display: none;
}

/* post: an X post screenshot with no title — the post text is the title. */
.crn-post .shot-frame {
  margin-top: 0;
}

/* Source captions: a small "出典" label, the page title, then the domain. */
.shot-caption .slot-body p::before {
  content: "出典";
  display: inline-block;
  margin-right: 12px;
  padding: 1px 8px;
  border: 1px solid var(--gold-600);
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: 14px;
  --peitho-lint-min-font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--gold-600);
  vertical-align: 2px;
}

.shot-caption .slot-body a {
  color: var(--fg3);
}

/* Same source label on guest lists and the closing note. */
.crn-year .slot-body p:last-child::before,
.statement-note .slot-body p:has(a)::before {
  content: "出典";
  display: inline-block;
  margin-right: 12px;
  padding: 1px 8px;
  border: 1px solid var(--gold-600);
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: 14px;
  --peitho-lint-min-font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--gold-600);
  vertical-align: 2px;
}

.crn-year .slot-body p:last-child a,
.statement-note .slot-body a {
  color: inherit;
}

/* Rule between the record and its source line. */
.shot-caption {
  padding-top: 14px;
  border-top: 1px solid var(--slate-300);
}

.crn-year .slot-body p:last-child,
.statement-note:has(a) {
  padding-top: 14px;
  border-top: 1px solid var(--slate-300);
}

/* --- year: dark divider. Year, event and venue on the left, that year's guests on the right. --- */

.crn-year {
  flex-direction: row;
  gap: 48px;
  background: var(--bg-dark);
  color: var(--fg-on-dark);
}

.year-left {
  flex: none;
  width: 380px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.year-right {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.crn-year h1 {
  font-size: 150px;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--slate-50);
}

.year-event {
  margin-top: 14px;
}

.year-event p {
  margin: 0;
  font-size: 26px;
  --peitho-lint-min-font-size: 26px;
  line-height: 1.3;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--cyan-400);
}

.year-event p + p {
  margin-top: 6px;
  font-size: 24px;
  --peitho-lint-min-font-size: 24px;
  font-weight: 400;
  color: var(--slate-300);
}

/* 20 ticks, 2006..2025. overrides.css marks past/current per slide key. */
.strip {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 14px;
  margin-top: 40px;
}

.strip i {
  flex: 1;
  height: 6px;
  border-radius: 2px;
  background: var(--slate-700);
}

.strip-lbl {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  font-size: 18px;
  --peitho-lint-min-font-size: 18px;
  letter-spacing: 0.08em;
  color: var(--slate-400);
}

.year-label {
  margin-bottom: 22px;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--gold-400);
}

.year-label p {
  margin: 0;
}

.peitho-slide[data-empty-slots~="label"] .year-label::before {
  content: "ゲスト";
}

.peitho-slide[data-empty-slots~="body"] .year-label {
  display: none;
}

.crn-year .crn-body {
  margin-top: 0;
}

.crn-year .slot-body {
  color: var(--fg-on-dark);
}

/* Two columns, but a name too long for half the width takes a row of its own
   instead of wrapping (a wrapped cell would stretch its whole grid row). */
.crn-year .slot-body ul {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
  font-size: 30px;
  --peitho-lint-min-font-size: 30px;
  padding: 0;
  list-style: none;
}

.crn-year .slot-body li {
  flex: 1 0 calc(50% - 20px);
  margin: 0;
  line-height: 1.4;
  white-space: nowrap;
}

/* Long lists (the years where many kickoff attendees also spoke) step the type
   down so the column keeps the same margins as the short years. */
.crn-year .slot-body ul:has(li:nth-child(12)) {
  gap: 10px 36px;
  font-size: 27px;
  --peitho-lint-min-font-size: 27px;
}

.crn-year .slot-body ul:has(li:nth-child(15)) {
  gap: 6px 32px;
  font-size: 25px;
  --peitho-lint-min-font-size: 25px;
}

.crn-year .slot-body ul:has(li:nth-child(18)) {
  gap: 4px 28px;
  font-size: 23px;
  --peitho-lint-min-font-size: 23px;
}

/* Three names or fewer read as one column: split across two, the last name wraps
   back to the left and the eye traces an N instead of going straight down. */
.crn-year .slot-body ul:not(:has(li:nth-child(4))) li {
  flex: 1 0 100%;
}

/* Note paragraph (2020: held in 2023 instead) and the source line. */
.crn-year .slot-body p {
  margin: 24px 0 0;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  color: var(--slate-400);
}

.crn-year .slot-body p:last-child {
  margin-top: 36px;
  font-size: 22px;
  --peitho-lint-min-font-size: 22px;
  border-top-color: var(--slate-700);
}

.crn-year .slot-body p:last-child::before {
  color: var(--gold-400);
  border-color: var(--gold-400);
}

.crn-year .slot-body p:last-child a {
  color: var(--slate-300);
}

/* --- eyebrow: the event name is an <em> at the head of a record's title --- */

.crn-shot h1 .slot-title > em {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--gold-600);
}

/* post: eyebrow on the left, the post date (inline code) as a chip on the right. */
.crn-post h1 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.crn-post h1 .slot-title {
  display: contents;
}

.crn-post h1 .slot-title > em {
  margin: 0;
}

.crn-post h1 .slot-title code {
  padding: 4px 14px;
  border: 1px solid var(--gold-600);
  border-radius: 999px;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--gold-600);
}

/* --- timeline (summary): notes above a row of 20 year dots --- */

.crn-timeline .tl-notes {
  position: relative;
  height: 262px;
  margin-top: auto;
}

.crn-timeline .tl-notes ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each note sits --row above the dot row and drops a leader line onto its year.
   overrides.css sets --row and the horizontal anchor per note. */
.crn-timeline .tl-notes li {
  position: absolute;
  bottom: var(--row);
  margin: 0;
  padding: 0 0 6px;
  font-size: 24px;
  --peitho-lint-min-font-size: 24px;
  line-height: 1.3;
  white-space: nowrap;
  color: var(--fg2);
}

.crn-timeline .tl-notes li::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 13px;
  width: 2px;
  height: calc(var(--row) + 12px);
  background: var(--slate-300);
}

.crn-timeline .tl-notes strong {
  margin-right: 10px;
  font-family: var(--font-display);
  font-size: 26px;
  --peitho-lint-min-font-size: 26px;
  color: var(--fg1);
}

.tl {
  display: grid;
  grid-template-columns: repeat(21, minmax(0, 1fr));
  gap: 8px;
  margin-top: 16px;
}

.tl > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.tl i,
.tl-legend i {
  display: block;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  box-sizing: border-box;
}

.tl .talk,
.tl-legend .talk {
  background: var(--accent);
}

.tl .att,
.tl-legend .att {
  border: 4px solid var(--cyan-600);
}

.tl .none,
.tl-legend .none {
  border: 2px solid var(--slate-200);
}

.tl .off,
.tl-legend .off {
  border: 2px dashed var(--slate-300);
}

.tl span {
  font-family: var(--font-display);
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  color: var(--fg4);
}

.tl-legend {
  display: flex;
  gap: 36px;
  margin-top: 40px;
  margin-bottom: auto;
  font-size: 22px;
  --peitho-lint-min-font-size: 22px;
  color: var(--fg3);
}

.tl-legend span {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.tl-legend i {
  width: 20px;
  height: 20px;
}

/* Year status chip: the event slot's third paragraph. **登壇** = gold dot,
   *参加* = cyan ring, plain text (参加なし / 開催なし) = grey ring. */
.year-event p:nth-of-type(3) {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  padding: 5px 15px 5px 11px;
  border: 1px solid var(--slate-600);
  border-radius: 999px;
  font-size: 20px;
  --peitho-lint-min-font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--slate-400);
}

.year-event p:nth-of-type(3)::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--slate-500);
  box-sizing: border-box;
}

.year-event p:nth-of-type(3) strong,
.year-event p:nth-of-type(3) em {
  font: inherit;
  color: inherit;
}

.year-event p:nth-of-type(3):has(> strong) {
  border-color: var(--gold-400);
  color: var(--gold-400);
}

.year-event p:nth-of-type(3):has(> strong)::before {
  border: 0;
  background: var(--gold-400);
}

.year-event p:nth-of-type(3):has(> em) {
  border-color: var(--cyan-400);
  color: var(--cyan-400);
}

.year-event p:nth-of-type(3):has(> em)::before {
  border: 3px solid var(--cyan-400);
}

/* --- nonext ("次のYAPCはない"): lead line, tally bar, lost/kept columns --- */

.crn-nonext .nonext-lead {
  margin-top: 36px;
}

/* No lead line on this deck's slide: drop its margin too, or it opens a gap
   between the title and the columns. */
.peitho-slide[data-empty-slots~="body"] .nonext-lead {
  display: none;
}

.crn-nonext .nonext-lead .slot-body p {
  margin: 0;
  font-size: 24px;
  --peitho-lint-min-font-size: 24px;
  line-height: 1.5;
  color: var(--fg3);
}

.nonext-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 56px;
  margin-top: 48px;
}

.nonext-h {
  margin-bottom: 16px;
  font-size: 24px;
  --peitho-lint-min-font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.14em;
}

.nonext-h.lost { color: var(--slate-400); }
.nonext-h.kept { color: var(--cyan-700); }

/* Colour carries the meaning here: the lost column fades out, the surviving one
   keeps full-strength ink. The heading pair does the same (slate-400 / cyan-700). */
.nonext-cols ul {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 30px;
  --peitho-lint-min-font-size: 30px;
  line-height: 1.8;
  color: var(--slate-700);
}

.nonext-cols > div:first-child ul {
  color: var(--slate-500);
}

.nonext-cols li {
  margin: 0;
}

/* --- profile: the 20-year strip, talk years gold and attended years cyan --- */

.profile-strip {
  width: 620px;
  margin-top: 30px;
}

.profile-strip .strip {
  margin-top: 0;
}

.profile-strip .strip i {
  background: var(--slate-700);
}

.profile-strip .strip i.att {
  background: var(--cyan-600);
}

.profile-strip .strip i.talk {
  height: 14px;
  background: var(--accent);
}

.profile-strip .strip-lbl {
  color: var(--slate-500);
}

.profile-strip .lg-talk::before,
.profile-strip .lg-att::before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 8px;
  border-radius: 2px;
  vertical-align: -1px;
}

.profile-strip .lg-talk { color: var(--gold-400); }
.profile-strip .lg-talk::before { background: var(--accent); }
.profile-strip .lg-att { color: var(--cyan-400); }
.profile-strip .lg-att::before { background: var(--cyan-600); }

/* --- source lines: always one line, long page titles end in an ellipsis --- */

.shot-caption .slot-body p,
.crn-year .slot-body p:last-child {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* --- Perl.org design system -----------------------------------------------
   Two brand colours carry everything: Perl blue #0073A1 is structure (nav,
   headings, links) and teal #61C5BA is the accent (the 2px rule under every
   h3, pills, tips). Amber #F0AD4E has exactly one job on the site — the active
   nav tab — so here it marks exactly one thing: the current year. The system
   is deliberately flat: no shadows anywhere, two background colours per screen
   at most, and the only two gradients are the navbar and the band under it. */

/* Headings are Perl blue, not near-black. perl.org sets h1 at light 300, but
   that is a weight for reading a page up close: projected, thin strokes are the
   first thing a room loses, and Japanese takes it worse than Latin because the
   fallback face carries the kanji. 400 keeps the site's lightness without
   dropping the title into the background. Section headings stay bold 700. */
.crn h1 {
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--perl-blue-dark);
}

.crn-shot h1 {
  font-weight: 700;
  color: var(--perl-blue-dark);
}

/* The site's one card is a solid Perl-blue slab, so the dark slides take the
   navbar gradient rather than a flat panel. */
.crn-cover,
.crn-profile,
.crn-year,
.crn-statement {
  background: var(--gradient-nav);
  color: var(--fg-on-dark);
}

.crn-cover h1,
.crn-profile h1,
.crn-statement h1 {
  color: #ffffff;
  font-weight: 400;
}

.crn-year .year-left h1 {
  color: #ffffff;
  font-weight: 400;
}

/* Uppercase 12px with 0.13em tracking is the interface voice — nav tabs and
   every button. The cover eyebrow and the 出典 label are this deck's version. */
.crn-cover .crn-inner::before {
  font-family: var(--font-sans);
  font-weight: 700;
  letter-spacing: 0.13em;
  color: var(--perl-teal);
}

/* Teal 2px rule under a heading: the system's most repeated device. */
.crn-shot h1 {
  padding-bottom: 12px;
  border-bottom: 2px solid var(--perl-teal);
}

.year-label {
  color: var(--perl-teal);
  letter-spacing: 0.13em;
  font-weight: 700;
}

/* On the blue ground the body text is white and the secondary tones are the
   tints the site uses for inactive nav text. */
.crn-year .year-event p {
  color: #ffffff;
}

.crn-year .year-event p + p,
.crn-profile .slot-body,
.crn-statement .statement-note,
.crn-statement .statement-note .slot-body p {
  color: rgba(255, 255, 255, .85);
}

.crn-profile .slot-body a {
  color: var(--perl-teal);
}

/* The closing's source reads like the year slides' source: body face, light grey. */
.crn-statement .statement-note a {
  color: var(--slate-300);
}

.crn-statement .statement-note:has(a) {
  border-top-color: rgba(255, 255, 255, .25);
}

.cover-meta {
  color: var(--perl-teal);
}

.cover-meta-sub,
.cover-meta-date {
  color: rgba(255, 255, 255, .85);
}

.profile-photo img {
  border-color: rgba(255, 255, 255, .35);
}

/* Flat system: nothing casts a shadow. */
.peitho-slide * {
  box-shadow: none;
}

/* Timeline states follow the system's own colour roles: Perl blue is structure
   so it marks 登壇, teal is the accent so it marks 参加, and the warm grey ramp
   carries the two "nothing happened" states. Filled vs outlined then reinforces
   a split that is already carried by hue. */
.tl .talk,
.tl-legend .talk {
  background: var(--perl-blue);
  border-color: var(--perl-blue);
}

.tl .att,
.tl-legend .att {
  border-color: var(--perl-teal);
}

.tl .none,
.tl-legend .none {
  border-color: var(--slate-400);
}

.tl .off,
.tl-legend .off {
  border-color: var(--slate-400);
}

.tl-legend {
  color: var(--fg3);
}

/* On the blue year slides the strip inverts: lit ticks in teal, the current
   year in amber — the site's one amber role, the active tab. */
.crn-year .strip i {
  background: rgba(255, 255, 255, .28);
}

.profile-strip .strip i {
  background: rgba(255, 255, 255, .28);
}

.profile-strip .strip i.talk {
  background: var(--perl-teal);
}

.profile-strip .strip i.att {
  background: rgba(255, 255, 255, .85);
}

/* The legend text sat in Perl blue, which disappears on the blue gradient the
   profile slide now uses; match each label to its own swatch instead. */
.profile-strip .lg-talk { color: var(--perl-teal); }
.profile-strip .lg-talk::before { background: var(--perl-teal); }
.profile-strip .lg-att { color: rgba(255, 255, 255, .85); }
.profile-strip .lg-att::before { background: rgba(255, 255, 255, .85); }
.profile-strip .strip-lbl { color: rgba(255, 255, 255, .85); }

/* The site's navbar gradient runs #0073A1 -> #003555, but a navbar is a 60px
   strip: its light end never has to carry small text. A full slide does, and on
   #0073A1 the system's own teal and amber land at 2.6:1. The gradient therefore
   starts at #00456E — $brand-primary before the 5% darken that yields #003555 —
   so the same accents clear 4.5:1 while staying inside the palette. */

/* The 出典 chip and the year slide's bullet markers use --gold-400/600, which in
   this palette is Perl blue — invisible on the blue gradient. On the light
   record slides blue is correct, so only the gradient slides are recoloured. */
.crn-year .slot-body p:last-child::before,
.crn-statement .statement-note .slot-body p:has(a)::before {
  border-color: var(--perl-teal);
  color: var(--perl-teal);
}

.crn-year .slot-body li::marker,
.crn-cover .slot-body li::marker,
.crn-statement .slot-body li::marker {
  color: var(--perl-teal);
}

/* On the white summary slide the brand teal is 2.1:1 and the light warm grey is
   2.4:1 — too faint for marks that carry meaning. Deepen 参加 to --cyan-700 and
   the empty states to the system's own $gray-base, both still in palette. The
   2px teal rule under a heading keeps the brand value: it is decoration, not a
   state, and it is how the site itself draws it. */
.tl .att,
.tl-legend .att {
  border-color: var(--cyan-700);
}

.tl .none,
.tl-legend .none,
.tl .off,
.tl-legend .off {
  border-color: var(--slate-500);
}

/* --- One scheme for 登壇 / 参加 everywhere --------------------------------
   The profile strip, the year strips and the year badges were each coloured
   separately, so the same word changed colour between slides: teal meant 登壇
   on the profile strip but 参加 on a year strip, and the 登壇 badge sat in Perl
   blue on the blue ground where it barely read. Bind all three to one pair of
   tokens instead: amber for 登壇, teal for 参加. Both clear 4.5:1 on the
   gradient, and amber keeps the site's "one job" rule by meaning exactly one
   thing across the deck. */
.crn-year,
.crn-profile {
  --state-talk: var(--perl-amber);
  --state-attend: var(--perl-teal);
}

/* Year badge */
.year-event p:nth-of-type(3):has(> strong) {
  border-color: var(--state-talk);
  color: var(--state-talk);
}

.year-event p:nth-of-type(3):has(> strong)::before {
  background: var(--state-talk);
}

.year-event p:nth-of-type(3):has(> em) {
  border-color: var(--state-attend);
  color: var(--state-attend);
}

.year-event p:nth-of-type(3):has(> em)::before {
  border-color: var(--state-attend);
}

/* Profile strip: the legend and its swatches follow the same pair. */
.profile-strip .strip i.talk { background: var(--state-talk); }
.profile-strip .strip i.att { background: var(--state-attend); }
.profile-strip .lg-talk { color: var(--state-talk); }
.profile-strip .lg-talk::before { background: var(--state-talk); }
.profile-strip .lg-att { color: var(--state-attend); }
.profile-strip .lg-att::before { background: var(--state-attend); }

/* The summary sits on white, where the gradient pair is far too pale: amber is
   1.95:1 and the brand teal 2.06:1. Keep the same two hues so 登壇/参加 read the
   same way as on the blue slides, but at weights that hold on white. */
.crn-timeline {
  --state-talk: #c8862c;
  --state-attend: var(--cyan-700);
}

.tl .talk,
.tl-legend .talk {
  background: var(--state-talk);
  border-color: var(--state-talk);
}

.tl .att,
.tl-legend .att {
  border-color: var(--state-attend);
}

/* Keyed overrides: every key must exist in the deck. */

/* whoami: web/GitHub/X icons before each link, same as the YAPC profile slide.
   Icons are the YAPC deck's white-on-black PNGs converted to link-cyan glyphs with
   luminance-as-alpha, inlined as data URIs so the build never has to copy them. */
[data-slide-key="whoami"] .slot-body a::before {
  content: "";
  display: inline-block;
  width: 26px;
  height: 26px;
  margin-right: 10px;
  vertical-align: -4px;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

[data-slide-key="whoami"] .slot-body a[href="https://mizzy.org"]::before {
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAClUExURSLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7v///6nnKIgAAAA1dFJOUwBqawxDo84Ibxvt/8HQSPlP/Yf/8oHpIiKYImEfVej+/RyZS8uvVvTp/aWAzf1kyusz/+OZwxvphwAAAAFiS0dENke/iNEAAAAHdElNRQfqCAEJMCgW5RtmAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI1LTA5LTE3VDEyOjE2OjEyKzAwOjAwif/V1AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyNS0wOS0xN1QxMjoxNTo1NSswMDowMFJ45h8AAAAodEVYdGRhdGU6dGltZXN0YW1wADIwMjYtMDgtMDFUMDk6NDg6NDArMDA6MDBfPR5hAAAA2UlEQVQoz4VSCW7CMBBciu2EhLNAAqUtd1vuc/7/tXrt2A5qUDeSR5qxZ68Q1agqXvT3T9SFVFBS1B/pKIaLOCrxjQQhkkbgPZlSU59Oifz9tEXU7iAp3Jx/ca/bQ2zrwaNAr4CpTRR83+ccQDBIDDMgz0deGEMyKLxRhlLxNIFiMOZZWXi3+RQ+9Pk5NTFjZm5fSCwYslDa0uYQWJG1dMLaVqX7+GJMvfBt+9Cd/zC0jDLdbHdF5zyrfTA7HE9uVjzd88VnCdM1+7je7vmffTzfYNXOq/8eol+bPCX68KDimQAAAABJRU5ErkJggg==");
}

[data-slide-key="whoami"] .slot-body a[href="https://github.com/mizzy"]::before {
  background-image: url("data:image/png;base64,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");
}

[data-slide-key="whoami"] .slot-body a[href="https://x.com/gosukenator"]::before {
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAGMUExURSLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7iLT7gAAAJx3gWEAAACCdFJOUwC3Vwy3TjwnBMXFBHP7CgCd8gwBvNAP56J6GRCDH11bKzFISytAQWQeiypbAKjnBt16C/6VG54AJ1VGxgRVJ4MOlf4L1LIACOeoGGkCtGRAM458EGyCEMq7AU80A9C8FXA3TBZzOzgjaTs8dROKciDBxQII3q8BAbt3ArPZBxBAEjBsOp4aAAAAAWJLR0SD/LTP0gAAAAd0SU1FB+oIAQkwKBblG2YAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjUtMDktMTdUMTI6Mjk6MjgrMDA6MDDL6bD1AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDI1LTA5LTE3VDEyOjI5OjI4KzAwOjAwurQISQAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyNi0wOC0wMVQwOTo0ODo0MCswMDowMF89HmEAAAEoSURBVCjPdZIFc8MwDIU15nXM0I6ZmTpmZmZex8ybfvmeYidtcjfd5fnpkxPLjon+iyAdwRYJCUWEUTjriNA8MgpJdAxRrC7ExRvclQCfmASXnMKcmpbOnGEUMmVSlmGz4XJyIXlI8oW79Vc98AWFkCIqFl5i9VGKrKwcUiG80t9yVTVzTW2daqI+cDMNjcxNzQZvabVtsw2ovQPS2eU4gG7AHi+k13k0fcz9A4PMQ8OOwsgo89g4Xpmw88kpWXl6BjJrK8ypXj3zkIUAvih0Cc/yCvPqmsXXhW9sbjFv78DtmnxP+D7RAYbDI8ix4ifCT8WdwZxfQHyS+YRfqjlXsNc3zLd3RPcPSB6fVOH5Rf/PV3p7x/DxaS73ZV4B+pYr8uNv/Fffmj9sY3xTa3yhowAAAABJRU5ErkJggg==");
}

/* year: progress strip — past ticks lit, the current year in gold. Prefix match covers
   the two-event years (y2017 + y2017f, y2024 + y2024hk). */
[data-slide-key^="y2006"] .strip i:nth-child(-n+1) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2006"] .strip i:nth-child(1) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2007"] .strip i:nth-child(-n+2) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2007"] .strip i:nth-child(2) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2008"] .strip i:nth-child(-n+3) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2008"] .strip i:nth-child(3) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2009"] .strip i:nth-child(-n+4) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2009"] .strip i:nth-child(4) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2010"] .strip i:nth-child(-n+5) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2010"] .strip i:nth-child(5) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2011"] .strip i:nth-child(-n+6) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2011"] .strip i:nth-child(6) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2012"] .strip i:nth-child(-n+7) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2012"] .strip i:nth-child(7) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2013"] .strip i:nth-child(-n+8) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2013"] .strip i:nth-child(8) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2014"] .strip i:nth-child(-n+9) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2014"] .strip i:nth-child(9) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2015"] .strip i:nth-child(-n+10) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2015"] .strip i:nth-child(10) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2016"] .strip i:nth-child(-n+11) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2016"] .strip i:nth-child(11) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2017"] .strip i:nth-child(-n+12) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2017"] .strip i:nth-child(12) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2018"] .strip i:nth-child(-n+13) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2018"] .strip i:nth-child(13) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2019"] .strip i:nth-child(-n+14) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2019"] .strip i:nth-child(14) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2020"] .strip i:nth-child(-n+15) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2020"] .strip i:nth-child(15) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2021"] .strip i:nth-child(-n+16) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2021"] .strip i:nth-child(16) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2022"] .strip i:nth-child(-n+17) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2022"] .strip i:nth-child(17) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2023"] .strip i:nth-child(-n+18) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2023"] .strip i:nth-child(18) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2024"] .strip i:nth-child(-n+19) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2024"] .strip i:nth-child(19) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2025"] .strip i:nth-child(-n+20) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2025"] .strip i:nth-child(20) { background: var(--state-talk); height: 14px; }
[data-slide-key^="y2026"] .strip i:nth-child(-n+21) { background: rgba(255,255,255,.55); }
[data-slide-key^="y2026"] .strip i:nth-child(21) { background: var(--state-talk); height: 14px; }

/* The rules above light the current tick in gold, which is the 登壇 colour, so every
   other year's tick contradicted its own badge. Recolour the tick to match: cyan on
   the years I attended, neutral on the years I did not. Gold is left to 登壇 alone
   (2007, 2008, 2009, 2012, 2025). Keep these lists in sync with each year's badge. */
[data-slide-key^="y2006"] .strip i:nth-child(1),
[data-slide-key^="y2010"] .strip i:nth-child(5),
[data-slide-key^="y2011"] .strip i:nth-child(6),
[data-slide-key^="y2013"] .strip i:nth-child(8),
[data-slide-key^="y2014"] .strip i:nth-child(9),
[data-slide-key^="y2015"] .strip i:nth-child(10) {
  background: var(--state-attend);
}

[data-slide-key^="y2016"] .strip i:nth-child(11),
[data-slide-key^="y2017"] .strip i:nth-child(12),
[data-slide-key^="y2018"] .strip i:nth-child(13),
[data-slide-key^="y2019"] .strip i:nth-child(14),
[data-slide-key^="y2020"] .strip i:nth-child(15),
[data-slide-key^="y2021"] .strip i:nth-child(16),
[data-slide-key^="y2022"] .strip i:nth-child(17),
[data-slide-key^="y2023"] .strip i:nth-child(18),
[data-slide-key^="y2024"] .strip i:nth-child(19) {
  background: rgba(255,255,255,.55);
}

/* base.css hides the ゲスト label only when the whole body slot is empty, but a year
   whose body holds just the 出典 link and no speaker list still showed a dangling
   label. Hide it whenever the body carries no list. */
.crn-year:not(:has(.slot-body ul)) .year-label {
  display: none;
}

/* summary: note anchors. Dot columns are 1104px / 21 (44.95px + 8px gap), so the
   centre of year i (0-based) is i * 52.95 + 22.5px; a note's edge sits 14px off it so
   the leader line (13px in from the edge) lands on the dot. Rows are chosen so no
   leader crosses another note. */
[data-slide-key="summary"] .tl-notes li:nth-child(1) { --row: 194px; left: 8px; }
[data-slide-key="summary"] .tl-notes li:nth-child(2) { --row: 132px; left: 61px; }
[data-slide-key="summary"] .tl-notes li:nth-child(3) { --row: 70px; left: 326px; }
[data-slide-key="summary"] .tl-notes li:nth-child(4) { --row: 8px; right: 167px; }
[data-slide-key="summary"] .tl-notes li:nth-child(5) { --row: 132px; right: 61px; }
[data-slide-key="summary"] .tl-notes li:nth-child(6) { --row: 194px; right: 8px; color: var(--accent-high); }
[data-slide-key="summary"] .tl-notes li:nth-child(4)::after,
[data-slide-key="summary"] .tl-notes li:nth-child(5)::after,
[data-slide-key="summary"] .tl-notes li:nth-child(6)::after { left: auto; right: 13px; }

/* The two bromide photo crops are small images; centre them in the frame instead of
   hanging them from the top like a screenshot. */
[data-slide-key="r-bromide-photo-09"] .slot-shot,
[data-slide-key="r-bromide-photo-10"] .slot-shot {
  align-items: center;
}

/* ...and scale them up to the frame height (the originals are ~430px and ~235px wide). */
[data-slide-key="r-bromide-photo-09"] .slot-shot img,
[data-slide-key="r-bromide-photo-10"] .slot-shot img {
  height: 100%;
  width: auto;
}