/* Tityra — the design system from the CLM research deck, carried to the web.
   One ink on gridded paper: nothing here uses a second colour to make a point. */

:root {
  /* Four colours, each with one job. Paper and Ink come from the CLM deck;
     Deep is the deck's own stage background, and the bird's black wings; Ring
     is the tityra's red eye-ring and bill base. See README for the rule. */
  --paper: #f0ebde;
  --ink: #1f2be0;
  --grid: #dbd8de;
  --deep: #11131f;
  --ring: #c8402c;

  --font-display: "Newsreader", "Noto Serif KR", Georgia, serif;
  --font-body: "Hanken Grotesk", "Noto Sans KR", system-ui, sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --measure: 68ch;
  --gutter: clamp(20px, 5vw, 64px);
  --rule: 1.5px solid var(--ink);
}

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

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

body {
  margin: 0;
  background-color: var(--paper);
  /* The deck's blueprint grid, at a size that stays quiet behind text. */
  background-image: linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 28px 28px;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  font-weight: 400;
}

.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------------------------------------------------------------- masthead */
.masthead {
  border-bottom: var(--rule);
  padding: 22px 0 18px;
  display: flex;
  align-items: baseline;
  gap: 18px;
  flex-wrap: wrap;
}

.masthead__mark {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
}

.masthead__mark img {
  width: 34px;
  height: 34px;
  flex: none;
  object-fit: contain;
}

.masthead__name {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
}

.masthead__nav {
  margin-left: auto;
  display: flex;
  gap: 20px;
}

.masthead__nav a,
.eyebrow {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.masthead__nav a {
  color: inherit;
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1.5px solid transparent;
}

.masthead__nav a:hover,
.masthead__nav a[aria-current="page"] {
  border-bottom-color: var(--ink);
}

/* The tagline sits under the rule like a dateline. */
.dateline {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 12px 0 0;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

/* -------------------------------------------------------------------- lede */
.lede {
  padding: clamp(40px, 9vw, 96px) 0 clamp(28px, 5vw, 56px);
  border-bottom: var(--rule);
}

.lede h1 {
  font-family: var(--font-display);
  font-size: clamp(44px, 11vw, 132px);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: -0.02em;
  margin: 0 0 22px;
}

.lede p {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1.35;
  max-width: 26ch;
  margin: 0;
}

/* ------------------------------------------------------------------ briefs */
.briefs {
  list-style: none;
  margin: 0;
  padding: 0;
}

.brief {
  border-bottom: 1px solid var(--ink);
  padding: 26px 0;
  display: grid;
  grid-template-columns: 148px 1fr;
  gap: var(--gutter);
  align-items: start;
}

.brief:last-child {
  border-bottom: 0;
}

.brief__meta {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding-top: 6px;
}

.brief__title {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.2vw, 36px);
  font-weight: 400;
  line-height: 1.18;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}

.brief__title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1.5px solid transparent;
}

.brief__title a:hover {
  border-bottom-color: var(--ink);
}

.brief__summary {
  margin: 0;
  max-width: var(--measure);
}

/* --------------------------------------------------------------- an article */
.article {
  padding: clamp(32px, 6vw, 72px) 0 0;
}

.article__header {
  border-bottom: var(--rule);
  padding-bottom: 22px;
  margin-bottom: 34px;
}

.article__header h1 {
  font-family: var(--font-display);
  font-size: clamp(32px, 5.4vw, 62px);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.02em;
  margin: 10px 0 0;
  max-width: 22ch;
}

.prose {
  max-width: var(--measure);
}

.prose h2 {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.8vw, 30px);
  font-weight: 500;
  line-height: 1.2;
  margin: 44px 0 12px;
}

.prose h3 {
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 700;
  margin: 30px 0 8px;
}

.prose p,
.prose li {
  margin: 0 0 16px;
}

.prose a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1.5px solid var(--ink);
}

.prose a:hover {
  background: var(--ink);
  color: var(--paper);
}

.prose code {
  font-family: var(--font-mono);
  font-size: 0.88em;
}

.prose pre {
  font-family: var(--font-mono);
  font-size: 13px;
  border: var(--rule);
  padding: 16px;
  overflow-x: auto;
  background: transparent;
}

.prose blockquote {
  margin: 24px 0;
  padding-left: 20px;
  border-left: var(--rule);
  font-family: var(--font-display);
  font-size: 20px;
}

/* An inverted block, as the deck uses for the node it wants you to look at. */
.callout {
  background: var(--ink);
  color: var(--paper);
  padding: 20px 22px;
  margin: 28px 0;
}

.callout .eyebrow {
  display: block;
  margin-bottom: 6px;
  opacity: 0.85;
}

/* Every item in a brief names where it came from. */
.sources {
  border-top: var(--rule);
  margin-top: 44px;
  padding-top: 18px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.8;
}

.sources ol {
  margin: 8px 0 0;
  padding-left: 1.6em;
}

.sources a {
  color: inherit;
}

/* ------------------------------------------------------------------ footer */
.foot {
  border-top: var(--rule);
  margin-top: clamp(48px, 9vw, 110px);
  padding: 18px 0 40px;
  display: flex;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.foot a {
  color: inherit;
}

@media (max-width: 640px) {
  .brief {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .masthead__nav {
    margin-left: 0;
    width: 100%;
  }
}

/* The deck is a light document; keep it one on every device rather than
   inventing a dark palette the design has never had. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #f0ebde;
    --ink: #1f2be0;
  }
}

/* ------------------------------------------------- a daily series, at scale */
/* The latest brief leads the home page; the rest are a compact list. */
.latest {
  padding: 22px 0 30px;
  border-bottom: var(--rule);
}

.latest__title {
  font-family: var(--font-display);
  font-size: clamp(30px, 5vw, 56px);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
  max-width: 22ch;
}

.latest__title a {
  color: inherit;
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.latest__title a:hover {
  border-bottom-color: var(--ink);
}

.latest__summary {
  margin: 0;
  max-width: var(--measure);
  font-family: var(--font-display);
  font-size: clamp(18px, 2.2vw, 22px);
  line-height: 1.4;
}

/* Month headings keep a year of dailies navigable. */
.month {
  padding-top: 30px;
}

.month__title {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  margin: 0 0 4px;
  padding-bottom: 8px;
  border-bottom: var(--rule);
  display: flex;
  justify-content: space-between;
}

.month__count {
  opacity: 0.6;
}

.more {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 22px 0 0;
}

.more a {
  color: inherit;
}

/* ---------------------------------------------------------------- motion */
/* The deck's own motion language, carried over with the type and the ink:
   --ease is its cubic-bezier, and it staggers entrances in 15ms steps. */
:root {
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --step: 0.015s;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.lede h1,
.lede p,
.latest,
.dateline,
.article__header,
.prose > *,
.reveal {
  animation: rise 0.55s var(--ease) both;
}

/* The stagger: each item enters one deck-step after the last. */
.lede p { animation-delay: calc(var(--step) * 4); }
.dateline { animation-delay: calc(var(--step) * 6); }
.latest { animation-delay: calc(var(--step) * 8); }
.brief:nth-child(1) { animation-delay: calc(var(--step) * 2); }
.brief:nth-child(2) { animation-delay: calc(var(--step) * 4); }
.brief:nth-child(3) { animation-delay: calc(var(--step) * 6); }
.brief:nth-child(4) { animation-delay: calc(var(--step) * 8); }
.brief:nth-child(5) { animation-delay: calc(var(--step) * 10); }
.brief:nth-child(n + 6) { animation-delay: calc(var(--step) * 12); }

/* Rows below the fold wait until they are scrolled to; the class is added by
   the script in the layout, and only when motion is welcome. */
.briefs .brief {
  animation: rise 0.5s var(--ease) both;
}

.js-reveal .brief,
.js-reveal .month {
  opacity: 0;
  animation: none;
}

.js-reveal .brief.is-in,
.js-reveal .month.is-in {
  animation: rise 0.5s var(--ease) both;
}

/* Interaction: the deck's ease on everything that responds to a pointer. */
.masthead__nav a,
.brief__title a,
.latest__title a,
.prose a,
.more a,
.sources a {
  transition:
    border-color 0.25s var(--ease),
    background-color 0.2s var(--ease),
    color 0.2s var(--ease);
}

.masthead__mark img {
  transition: transform 0.4s var(--ease);
}

.masthead__mark:hover img {
  transform: translateY(-2px) rotate(-4deg);
}

.brief {
  transition: background-color 0.3s var(--ease);
}

.brief:hover {
  background-color: rgba(31, 43, 224, 0.04);
}

/* Motion is decoration. Readers who ask for less get none of it, and the page
   must be complete and readable without a single frame having played. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  .js-reveal .brief,
  .js-reveal .month {
    opacity: 1;
  }
}

/* ===================================================== depth without colour
   The site stays one ink. Warmth and activity come from paper tone, motion,
   typographic scale and the bird — not from a second hue. */

/* --- 1 · the heartbeat ---------------------------------------------------
   A wire service is a thing that is alive and delivers every morning. */
.pulse {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink);
  margin-left: 2px;
  vertical-align: baseline;
  animation: beat 3.2s var(--ease) infinite;
}

@keyframes beat {
  0%, 62%, 100% { transform: scale(1); opacity: 0.85; }
  8% { transform: scale(1.5); opacity: 1; }
  16% { transform: scale(1); opacity: 0.85; }
  24% { transform: scale(1.32); opacity: 1; }
  32% { transform: scale(1); opacity: 0.85; }
}

/* --- 3 · the deck's progress line ---------------------------------------- */
.progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--ink);
  z-index: 50;
  transition: width 0.1s linear;
}

/* --- 4 · figures as typographic objects ----------------------------------
   Populated from front matter, never scraped from the prose: a number pulled
   out of a sentence by a script is a number that can be misattributed, and
   this site's whole contract is that figures are quoted, not inferred. */
.figures {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(22px, 5vw, 56px);
  padding: 26px 0 30px;
  border-bottom: var(--rule);
}

.figures__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.figures__value {
  font-family: var(--font-display);
  font-size: clamp(30px, 5.2vw, 54px);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.figures__label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
  opacity: 0.72;
  max-width: 30ch;
}

.figures__item {
  min-width: 0;
  flex: 1 1 200px;
  max-width: 320px;
}

/* --- 5 · paper strata ----------------------------------------------------
   Two percent of warmth, invisible as colour and felt as depth. A slide is
   flat because it is one screen; a page you scroll wants layers. */
.band {
  position: relative;
}

.band::before {
  content: "";
  position: absolute;
  inset: 0 calc(var(--gutter) * -1);
  background: #ece6d6;
  opacity: 0.55;
  z-index: -1;
  pointer-events: none;
}

.brief:nth-child(even) {
  background-color: rgba(214, 203, 178, 0.32);
  padding-left: 14px;
  padding-right: 14px;
  margin-left: -14px;
  margin-right: -14px;
}

/* --- 6 · the tail as the rule --------------------------------------------
   Cyanopica-style: the tityra's long tail drawn as the divider, so the brand
   becomes the layout instead of sitting in a corner. */
.tail {
  display: block;
  width: 100%;
  height: 14px;
  margin: 8px 0 0;
  color: var(--ink);
}

.tail svg {
  display: block;
  width: 100%;
  height: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .pulse { animation: none; }
  .progress { transition: none; }
}

/* The largest type on the page should also be the most checkable: a figure
   links to the source that states it. */
a.figures__value {
  color: inherit;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 0.25s var(--ease);
}

a.figures__value:hover {
  border-bottom-color: var(--ink);
}

/* Visit counts, read back from GoatCounter. Hidden until they actually load:
   a footer that says "0 today" because a request was blocked is worse than a
   footer that says nothing. */
.tally {
  font-variant-numeric: tabular-nums;
}


/* ======================================================= the four colours ===
   Deep carries weight: headlines and the figures strip stop being the same
   blue as the body, which is most of the hierarchy this page was missing.
   Ink keeps body text, links and rules. Ring marks one thing and no more. */

.lede h1,
.article__header h1,
.latest__title,
.latest__title a,
.brief__title,
.brief__title a,
.prose h2,
.prose h3,
.masthead__name,
.month__title {
  color: var(--deep);
}

.brief__title a:hover,
.latest__title a:hover {
  border-bottom-color: var(--deep);
}

.figures {
  color: var(--deep);
  background: rgba(17, 19, 31, 0.045);
  border-bottom-color: var(--deep);
  padding-left: 18px;
  padding-right: 18px;
  margin-left: -18px;
  margin-right: -18px;
}

a.figures__value:hover {
  border-bottom-color: var(--deep);
}

/* --- bold: the accent inside a sentence --------------------------------
   Ink reads, Deep points. Weight is the second half of that: a bold phrase
   leaves the blue and lands in Deep, so an accent is one signal made of two
   parts rather than two signals competing.

   A bold run that opens a bullet is structure, not emphasis — it is the
   item's name — so it takes the body face at 600 and sits with the headings.
   Bold inside a sentence stays at 700, where it has to cut through text that
   is already the same size. */
.prose strong,
.prose b {
  color: var(--deep);
  font-weight: 700;
}

.prose li > strong:first-child,
.prose li > b:first-child,
.prose li > p:first-child > strong:first-child {
  font-family: var(--font-body);
  font-weight: 600;
}

/* A bold phrase inside a link would read as two accents at once; the link's
   own underline is already the signal there. */
.prose a strong,
.prose a b {
  color: inherit;
  font-weight: 600;
}

/* --- Ring: the one marker ------------------------------------------------
   The live dot, and "new since your last visit". Never a text colour: on
   paper its contrast is weaker than Ink, so it marks and never reads. */
.pulse {
  background: var(--ring);
}

.is-new {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ring);
  padding: 2px 7px;
  margin-left: 8px;
  vertical-align: 3px;
  white-space: nowrap;
}


/* On paper, nothing is scrolled into view: the reveal must never hide a brief
   from print. Same reasoning as the failsafe in the layout script. */
@media print {
  .js-reveal .brief,
  .js-reveal .month {
    opacity: 1 !important;
    animation: none !important;
  }
  .progress,
  .masthead__nav {
    display: none;
  }
}
