/* IZUNAWORKS v2 — the eight public routes.
 *
 * Loaded after site.css, which owns the tokens, the header and the footer.
 * Built from Figma section "02 · Routes" (node 34:99): /works, /terms,
 * /about-me, /contact, /product-license, /privacy-policy, /works/[slug]
 * and /404. Lengths are the artboard's own.
 *
 * Two things in here are NOT the home page's grammar, and both are the
 * artboard's doing rather than an oversight:
 *   * /product-license and /privacy-policy set their page title in Zen Kaku
 *     Gothic New 36px, not Satoshi 35.943 like the other five. Their heading
 *     block is 413x81 with a 1px rule instead of 413.245x86.923 at 1.377.
 *   * /works/<slug> labels its meta rows in Inter, a face that appears
 *     nowhere else on the site. It is subset to Latin for exactly this use.
 */

/* font-display is `block` here for the same reason as in site.css — read the
 * fonts note there before changing it. Satoshi Black is painted by /404 alone
 * and Inter by /works/<slug> alone, so only those two pages preload them. */
@font-face {
  font-family: 'Satoshi';
  src: url('/assets/fonts/Satoshi-Black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: block;
}
/* Zen Kaku Gothic New Medium is painted by /about-me alone — the 使用ソフト
 * chips — so only that page preloads it. The file is the full family in
 * woff2, the same as the Regular and Bold beside it in site.css. */
@font-face {
  font-family: 'Zen Kaku Gothic New';
  src: url('/assets/fonts/ZenKakuGothicNew-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/Inter-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

:root {
  --meta: 'Inter', 'Satoshi', system-ui, sans-serif;
}

/* ---------- the shared route shell ---------- */

.page {
  display: flex;
  flex-direction: column;
  gap: 47px;
  /* The artboard's Content frame: 64 top and bottom, 100 either side. */
  padding: 64px var(--sec-pad);
  /* Every route frame is at least 1000 tall, which is what keeps the footer
     off the fold on a short page. */
  min-height: 1000px;
}

.page--center { justify-content: center; align-items: center; }

.page__heading { display: flex; flex-direction: column; align-items: flex-start; }

.page__title {
  font-family: var(--en);
  font-weight: 700;
  font-size: 35.943px;
  line-height: 48.524px;
  color: var(--red);
}

.page__rule {
  width: 413.245px;
  max-width: 100%;
  height: 0;
  border: 0;
  border-top: 1.377px solid var(--red);
  margin: 0;
}

.page__subtitle {
  padding-top: 14px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 15px;
  line-height: 24px;
  color: var(--ink);
}

/* The legal pages' dateline (owner, 2026-09-23). A policy with no effective
   date is the thing that makes it read as a notice rather than a document, so
   both /product-license and /privacy-policy carry one under the subtitle. It
   is `license.updated` / `privacy.updated`, typed in the console exactly as it
   is shown -- the same plain-string convention every other date on this site
   uses -- and the row is `hidden` until the document has one, so a blank
   never leaves an orphan line under the rule. */
.page__meta {
  padding-top: 6px;
  font-family: var(--en);
  font-weight: 500;
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, 0.45);
}

/* The legal pages' heading — see the note at the top of this file. */
.page__title--jp {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 36px;
  line-height: 43.2px;
}

.page__rule--jp { width: 413px; border-top-width: 1px; }

@media (max-width: 680px) {
  .page { padding: 44px var(--sec-pad); min-height: 0; }
  .page__title { font-size: 26px; line-height: 1.35; }
  .page__title--jp { font-size: 26px; line-height: 1.35; }
}

/* ---------- /works ---------- */

/* The grid itself is the home page's .works__grid, reused unchanged. Rows of
   three stack with the same 86px gutter the artboard uses between columns. */
.works__grid--page { row-gap: 56px; }

/* ---------- /terms ---------- */

.checklist { display: flex; flex-direction: column; gap: 32px; }

.check {
  display: flex;
  gap: 24px;
  width: 1040px;
  max-width: 100%;
}

.check__num {
  flex: none;
  width: 34px;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 17px;
  line-height: 25.5px;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}

.check__copy { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

.check__title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 17px;
  line-height: 25.5px;
  color: var(--ink);
}

/* The artboard drops the body to 72% rather than to a grey, so it stays in
   the ink colour and keeps working if the palette ever changes. */
.check__body {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 25.2px;
  color: var(--ink);
  opacity: 0.72;
  white-space: pre-line;
}

/* ---------- /about-me ---------- */

/* 480 figure + 80 gutter + 1160 of details, as the artboard's Profile frame
   (node 35:223) lays it out. The figure is fixed; the details take the rest. */
.profile {
  display: flex;
  gap: 80px;
  width: 1720px;
  max-width: 100%;
}

/* The square holds the photograph's place and draws nothing else — no plate
   and, since about-me.html stopped carrying it, no "480 × 480" copy. The size
   stays so the bio beside it does not move when the picture lands. */
.profile__figure {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 480px;
  height: 480px;
  max-width: 100%;
  overflow: hidden;
  background: transparent;
}

.profile__figure img { width: 100%; height: 100%; object-fit: cover; }

.profile__details {
  display: flex;
  flex-direction: column;
  gap: 56px;
  flex: 1 1 0;
  min-width: 0;
}

/* Bio beside the software list: 640 of prose, an 80 gutter, a 440 column. */
.profile__row { display: flex; gap: 80px; align-items: flex-start; }

.profile__bio { display: flex; flex-direction: column; gap: 14px; flex: 1 1 640px; min-width: 0; }

.profile__name {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 26px;
  line-height: 36.4px;
  color: var(--ink);
}

.profile__role {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 15px;
  line-height: 24px;
  color: var(--ink);
}

.profile__body {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 22.4px;
  color: var(--ink);
  white-space: pre-line;
}

/* ---- 使用ソフト and 制作内容 ---- */

/* A titled block: 16px bold heading, a hairline 10px under it, the list 16px
   below that. Both blocks are hidden until the document fills them — see the
   comment in about-me.html. */
.block { display: flex; flex-direction: column; gap: 16px; width: 100%; min-width: 0; }
.block--software { flex: none; width: 440px; max-width: 100%; }

.block__heading { display: flex; flex-direction: column; gap: 10px; }

.block__title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 16px;
  line-height: 22.4px;
  color: var(--ink);
}

.block__rule {
  width: 100%;
  height: 0;
  border: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.14);
  margin: 0;
}

/* The software chips: white on the page's grey, a hairline edge, a 24px
   glyph and the name in Medium. They wrap into as many rows as they need. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px 10px 12px;
  background: var(--surface);
  border: 1px solid #d9d9d9;
  font-family: var(--jp);
  font-weight: 500;
  font-size: 14px;
  line-height: 22.4px;
  color: var(--ink);
  white-space: nowrap;
}

/* A chip without a glyph keeps the wider 16px on both sides. */
.chip--plain { padding-left: 16px; }

.chip__icon { flex: none; width: 24px; height: 24px; object-fit: contain; }

/* The service cards: equal width, a 20px gutter, and as many across as fit at
   400 wide. A card that cannot have 400 wraps to the next row at the same size
   rather than shrinking the row it is in.

   400 is a floor, not a width (2026-09-23). Three across inside
   .profile__details is 368 on a 1920 screen — the photograph and its 80 gutter
   come out of the same row — and at 368 the body has 318 of text, which is 22
   Japanese characters. Every line the owner writes longer than that wraps, so
   a three-line 制作内容 came out six lines deep. The floor turns the row into
   two of 562, which holds the lines as typed.

   `min(400px, 100%)` rather than a bare 400: below that the floor would be
   wider than the row itself and auto-fit would run the cards off the page.
   That is also what replaces the old single-column breakpoint. */
.services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
  gap: 20px;
}

.service {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Even now that the 01/02/03 line is gone and the title is the first row. */
  padding: 24px;
  background: var(--surface);
  border: 1px solid #d9d9d9;
  min-width: 0;
}

.service__title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 17px;
  line-height: 25.5px;
  color: var(--ink);
}

/* 72% ink rather than a grey, for the same reason as .check__body. */
.service__body {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 22.4px;
  color: var(--ink);
  opacity: 0.72;
  white-space: pre-line;
}

/* Stacked, the bio's 640 flex-basis would become a 640 HEIGHT; drop it. */
@media (max-width: 1500px) {
  .profile__row { flex-direction: column; gap: 40px; }
  .profile__bio { flex: none; }
  .block--software { width: 100%; }
}

@media (max-width: 1100px) {
  .profile { flex-direction: column; gap: 40px; }
  .profile__figure { width: 100%; height: auto; aspect-ratio: 1; }
}

/* ---------- /contact ---------- */

.columns { display: flex; gap: 100px; width: 1720px; max-width: 100%; }

@media (max-width: 1280px) {
  .columns { flex-direction: column; gap: 56px; }
}

.cinfo { display: flex; flex-direction: column; gap: 16px; width: 560px; max-width: 100%; flex: none; }

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

/* The label row and the reply row both sit at 55% — the artboard's way of
   holding a caption back without inventing a grey. */
.cinfo__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.6px;
  color: var(--ink);
  opacity: 0.55;
}

.cinfo__label img { width: 16px; height: 16px; flex: none; }

.cinfo__value {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 22px;
  line-height: 30.8px;
  color: var(--ink);
  word-break: break-all;
}

a.cinfo__value:hover { color: var(--red); }

.cinfo__reply {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 22px;
  color: var(--ink);
  opacity: 0.72;
}

.cinfo__reply img { width: 16px; height: 16px; flex: none; margin-top: 3px; opacity: 0.55; }

.ask { display: flex; flex-direction: column; gap: 20px; width: 1060px; max-width: 100%; min-width: 0; }

.ask__heading {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 20px;
  line-height: 30px;
  color: var(--red);
}

.ask__note {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 22px;
  color: var(--ink);
}

.ask__note img { width: 16px; height: 16px; flex: none; margin-top: 3px; }

.ask__btn {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 6px;
  padding: 11px 16px 11px 20px;
  background: var(--red);
  font-family: var(--jp);
  font-weight: 700;
  font-size: 14px;
  line-height: 20px;
  color: var(--surface);
  white-space: nowrap;
}

/* Hover is the shared button sweep in site.css's motion section. */
.ask__btn img { width: 20px; height: 20px; flex: none; }

.ask__template-note {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 25.2px;
  color: var(--ink);
}

.tpl {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px 32px;
  background: var(--surface);
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

.tpl__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 14px;
  line-height: 22px;
  color: var(--ink);
}

.tpl__label img { width: 16px; height: 16px; flex: none; }

.tpl__body {
  margin: 0;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  /* The artboard sets each line 32px apart: 22.4 of leading plus the card's
     own 10px gap between rows. */
  line-height: 32px;
  color: var(--ink);
  white-space: pre-line;
}

.tpl__copy {
  align-self: flex-start;
  margin-top: 6px;
  padding: 7px 14px;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  background: transparent;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 12.5px;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease;
}

.tpl__copy:hover { border-color: var(--red); color: var(--red); }

/* ---------- /product-license, /privacy-policy: one Markdown document each ---------- */

/* Since 2026-09-22 both legal pages are a single Markdown text (see
   js/markdown.js) rather than four heading+body rows. EVERY heading is
   painted in the site red, which is the one thing the owner asked for by
   name: headings pick out red on their own, nothing to set per line.
   `#` in the text is an <h2> here because the page's <h1> is the title block.

   THE MEASURE IS THE WHOLE POINT OF THIS BLOCK (owner, 2026-09-23: the legal
   pages are hard to read). It was `width: 1720px` -- the full content frame --
   which put about 100 Japanese characters on a line at 1920. Reading research
   puts the comfortable range at 35-45; past roughly 60 the eye loses its place
   on the return sweep, which is exactly what a wall of policy text feels like.
   680px at 15.5px is ~44, and it is the same 680 canon the Flutter site's
   content pages settled on. This is NOT the narrow-column layout the owner
   rejected in 2026-08 -- that was a 300px rail chopping headings into
   two-word lines. One column at a reading measure is the opposite of it.

   The rest of the block follows from that one number:
     - 15.5/31 rather than 14/25.2. A page read once, slowly, not a caption.
     - body ink at 86% rather than 72%. 72% grey reads as a draft; a document
       someone is meant to be bound by should be set in something close to ink.
     - 60px above an h2 against 20px between paragraphs. The old 40-against-14
       was too close to tell a new section from a new paragraph.
   `.doc` is shared with /news/<slug>, which gets the same measure -- it is
   prose too, and it was 1720 for the same reason. */

.doc {
  width: 680px;
  max-width: 100%;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 15.5px;
  line-height: 31px;
  color: var(--ink);
}

.doc > * + * { margin-top: 20px; }

.doc h2,
.doc h3,
.doc h4,
.doc h5,
.doc h6 {
  font-family: var(--jp);
  font-weight: 700;
  color: var(--red);
}

.doc > :first-child { margin-top: 0; }

.doc h2 { font-size: 19px; line-height: 28px; margin-top: 60px; }
.doc h3 { font-size: 16px; line-height: 26px; margin-top: 44px; }
.doc h4 { font-size: 15.5px; line-height: 26px; margin-top: 36px; }
.doc h5,
.doc h6 { font-size: 15px; line-height: 26px; margin-top: 30px; }

/* A heading and the line under it belong together, so the paragraph that
   follows one sits closer than 20px. Written as `h2 + *` rather than on the
   heading's own margin-bottom so it beats `.doc > * + *` on specificity. */
.doc h2 + *,
.doc h3 + *,
.doc h4 + *,
.doc h5 + *,
.doc h6 + * { margin-top: 14px; }

/* Body ink. 72% was the old section bodies' grey and it read as a draft on a
   page this long; 86% is still quieter than a heading and still clearly ink.
   Rules and code stay at full ink (or red) so the structure reads through. */
.doc p,
.doc li,
.doc td,
.doc blockquote { opacity: 0.86; }
.doc li p { opacity: 1; }

.doc a { text-decoration: underline; text-underline-offset: 3px; }
.doc a:hover { color: var(--red); }

.doc strong { font-weight: 700; }
.doc em { font-style: italic; }
.doc del { text-decoration: line-through; }

.doc ul,
.doc ol { padding-left: 1.5em; }
.doc ul { list-style: disc; }
.doc ol { list-style: decimal; }
.doc li + li { margin-top: 8px; }
.doc li > ul,
.doc li > ol { margin-top: 8px; }

.doc blockquote {
  padding: 2px 0 2px 18px;
  border-left: 2px solid var(--red);
}

.doc hr {
  height: 0;
  border: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.18);
  margin-top: 28px;
  margin-bottom: 28px;
}

.doc code {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, Menlo, monospace;
  font-size: 0.92em;
  padding: 1px 5px;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 2px;
}

.doc pre {
  padding: 14px 18px;
  overflow-x: auto;
  background: rgba(0, 0, 0, 0.04);
  border-radius: 2px;
  line-height: 1.7;
}

.doc pre code { padding: 0; background: none; font-size: 12.5px; }

.doc table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  line-height: 22px;
}

.doc th,
.doc td {
  padding: 9px 14px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}

.doc th { font-weight: 700; border-bottom-color: var(--red); }

.doc img { max-width: 100%; height: auto; display: block; }

/* ---------- /works/[slug] ---------- */

.detail { display: flex; flex-direction: column; gap: 0; }

.crumb {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 19px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 13px;
  line-height: 18.824px;
  color: rgba(0, 0, 0, 0.4);
}

.crumb a:hover { color: var(--red); }
.crumb__here { color: rgba(0, 0, 0, 0.8); }

/* Wrap between crumbs, never inside one: a long crumb ("ANNOUNCEMENT" on a
   phone) used to break mid-word because the row could not wrap. The current
   page is the one crumb allowed to run onto a second line. */
.crumb { flex-wrap: wrap; row-gap: 2px; }
.crumb > a,
.crumb > span { white-space: nowrap; }
.crumb__here { white-space: normal; overflow-wrap: anywhere; }

/* EVERY MEDIA FRAME IS THE ARTBOARD'S BIG ONE (owner-directed, 2026-09-22).

   The artboard drew one 780x439 frame with two 260x212 boxes beside it, and
   those two were too small to read: a 16:9 clip letterboxed inside 260x212 is
   a smear, and a still was cropped to a strip. The second and third media now
   sit UNDER the first at the same 780x439, so the column's width — and with
   it the meta column at 618, which does not move — is still the artboard's.
   780 / 14 / 260 / 48 / 618 out of 1720: the middle three are now one empty
   gutter (0.814 + 15.116 + 2.791), so the proportions are unchanged. */
.detail__top {
  display: grid;
  grid-template-columns: 45.349% 18.721% 35.93%;
  align-items: start;
}

.detail__media { grid-column: 1; display: flex; flex-direction: column; gap: 14px; }
.detail__meta { grid-column: 3; }

.media {
  position: relative;
  overflow: hidden;
  border-radius: 2px;
  background: #dedede;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 780 / 439;
}

.media img,
.media iframe { width: 100%; height: 100%; border: 0; object-fit: cover; display: block; }

/* A self-hosted clip fills the frame like the YouTube embed it replaces, but
   is CONTAINED rather than cropped: the owner's own file is framed the way
   they exported it, and cropping a render that is not exactly 780x439 would
   cut the edges off their work. */
.media video {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  object-fit: contain;
  background: #000000;
}

/* Audio has no picture, so it sits on the frame's own background rather than
   stretching a control bar to 439px tall. */
.media audio { width: calc(100% - 28px); }

/* A PDF or an archive: nothing to paint, so the frame becomes the link. */
.media__file {
  max-width: calc(100% - 28px);
  font-family: var(--meta);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  text-align: center;
  overflow-wrap: anywhere;
}

.media__placeholder {
  font-family: var(--meta);
  font-weight: 400;
  font-size: 16px;
  color: rgba(0, 0, 0, 0.3);
}

.detail__title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 22px;
  line-height: 30.8px;
  color: var(--ink);
}

.detail__cover {
  display: inline-flex;
  align-items: center;
  margin-top: 12px;
  padding: 3px 9px;
  border: 1.5px solid var(--red);
  border-radius: 2px;
  font-family: var(--meta);
  font-weight: 700;
  font-size: 11px;
  line-height: 13.3px;
  color: var(--red);
}

.detail__rows { margin-top: 20px; }

.mrow { padding-bottom: 10px; border-bottom: 0.5px solid rgba(0, 0, 0, 0.1); margin-bottom: 15px; }

.mrow__label {
  font-family: var(--meta);
  font-weight: 700;
  font-size: 11px;
  line-height: 13.3px;
  color: rgba(0, 0, 0, 0.38);
}

.mrow__value {
  margin-top: 3px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 14px;
  line-height: 22.4px;
  color: var(--ink);
  white-space: pre-line;
}

.detail__divider {
  height: 0;
  margin: 52px 0 36px;
  border: 0;
  border-top: 0.5px solid rgba(0, 0, 0, 0.12);
}

@media (max-width: 1100px) {
  .detail__top { grid-template-columns: 1fr; gap: 14px; }
  .detail__media, .detail__meta { grid-column: 1; }
  .detail__meta { margin-top: 20px; }
}

/* ---------- /404 ---------- */

.nf { display: flex; flex-direction: column; align-items: center; gap: 40px; text-align: center; }

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

.nf__code {
  font-family: var(--en);
  font-weight: 900;
  font-size: 128px;
  line-height: 172.8px;
  letter-spacing: -2.56px;
  color: var(--red);
}

.nf__rule { width: 220px; height: 2px; background: var(--red); }

.nf__text { display: flex; flex-direction: column; align-items: center; gap: 14px; }

.nf__headline {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 22px;
  line-height: 31.856px;
  color: var(--ink);
}

.nf__body {
  max-width: 478px;
  font-family: var(--jp);
  font-weight: 400;
  font-size: 15px;
  line-height: 28.5px;
  color: #666666;
}

.nf__btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 18px 32px;
  background: var(--red);
  font-family: var(--jp);
  font-weight: 700;
  font-size: 15px;
  line-height: 21.72px;
  color: var(--surface);
}

/* Hover is the shared button sweep in site.css's motion section. */
.nf__btn img { width: 18px; height: 18px; flex: none; }

@media (max-width: 680px) {
  .nf__code { font-size: 76px; line-height: 1.1; letter-spacing: -1.5px; }
}

/* ---------- empty states ---------- */

.empty-note {
  font-family: var(--jp);
  font-size: 15px;
  line-height: 1.8;
  color: var(--placeholder-ink);
}

/* ---------- selection ---------- */

/* The route pages' half of the rule documented in css/site.css: chrome is not
   copy. Headings, numbers, labels, buttons and the placeholder words inside an
   empty media box do not select; the prose beside them — .check__body,
   .profile__body, .service__body, .tpl__body, .ask__note, .cinfo__value,
   .mrow__value, .nf__body — deliberately still does, because that text is the
   reason someone is on the page. The legal pages' .doc is copy from top to
   bottom, headings included: someone copying a licence wants its headings.
   Keep that split when adding a route. */

.page__heading,
.check__num,
.check__title,
.profile__name,
.profile__role,
.block__title,
.chip,
.service__title,
.cinfo__label,
.ask__heading,
.ask__btn,
.tpl__label,
.tpl__copy,
.crumb,
.media__placeholder,
.media__file,
.detail__title,
.detail__cover,
.mrow__label,
.nf__title,
.nf__headline,
.nf__btn {
  -webkit-user-select: none;
  user-select: none;
}

/* ---------- /news ---------- */

/* EVERY POST UNDER ITS NUMBER (owner-picked "04", 2026-09-25).

   This was an open ledger of hairline-ruled rows (2026-09-22); the owner did
   not like it, and picked this from six alternatives. Each post stands beside
   a large number -- its place from the top, so the newest is always 01
   (newsNumber() in js/site.js; owner, 2026-09-25) -- in red, and the rest a
   faint grey. Whitespace separates the entries: no rules,
   which is also what the FAQ taught (bare ruled rows were rejected twice).
   The count sits opposite the heading. The home page's section is the same
   family ("H3"), four across. */

.feed__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 24px;
}

.feed__count {
  font-family: var(--en);
  font-weight: 700;
  font-size: 14px;
  line-height: 24px;
  letter-spacing: 0.18em;
  color: rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}

.feed {
  display: flex;
  flex-direction: column;
  gap: 60px;
  width: 1720px;
  max-width: 100%;
  margin-top: 25px;
}

.entry {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) 40px;
  align-items: center;
  column-gap: 40px;
  color: var(--ink);
}

.entry__no {
  font-family: var(--en);
  font-weight: 700;
  font-size: 112px;
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: rgba(0, 0, 0, 0.12);
}

.entry--latest .entry__no { color: var(--red); }

.entry__copy { display: flex; flex-direction: column; gap: 10px; min-width: 0; }

.entry__date {
  font-family: var(--en);
  font-weight: 500;
  font-size: 15px;
  line-height: 22px;
  letter-spacing: 0.06em;
  color: rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}

.entry__title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.45;
  color: var(--ink);
  overflow-wrap: anywhere;
  transition: color 160ms ease;
}

/* One line of the body. It is a quote, so it is the only piece of the entry
   that still selects (see the selection note). */
.entry__excerpt {
  font-family: var(--jp);
  font-weight: 400;
  font-size: 15px;
  line-height: 1.8;
  color: rgba(0, 0, 0, 0.6);
  overflow-wrap: anywhere;
}

.entry__arrow {
  width: 32px;
  height: 32px;
  flex: none;
  transition: transform 160ms ease;
}

/* The same response as the WORKS card: the type answers, nothing else moves
   (owner, 2026-09-22 -- hover lives in the type). */
.entry:hover .entry__title { color: var(--red); }
.entry:hover .entry__arrow { transform: translateX(4px); }

@media (max-width: 1100px) {
  .entry { grid-template-columns: 150px minmax(0, 1fr) 32px; column-gap: 28px; }
  .entry__no { font-size: 88px; }
  .entry__title { font-size: 25px; }
  .entry__arrow { width: 28px; height: 28px; }
}

@media (max-width: 680px) {
  .feed { gap: 36px; margin-top: 0; }
  .entry {
    grid-template-columns: 72px minmax(0, 1fr);
    column-gap: 16px;
    align-items: start;
  }
  .entry__no { font-size: 56px; }
  .entry__copy { gap: 6px; }
  .entry__date { font-size: 13px; line-height: 20px; }
  .entry__title { font-size: 19px; }
  .entry__excerpt { font-size: 14px; }
  .entry__arrow { display: none; }
}

/* ---------- /news/[slug] ---------- */

/* One announcement. The head is the route heading turned the other way
   round: the date small and grey where a subtitle would be, the title in ink
   at the size the legal pages' title uses, and the same 413 red rule under
   it -- so the page is recognisably one of this site's, but a post, not a
   section. The body is .doc, shared with the legal pages, which is what makes
   a `#` in the owner's text come out red here too. */

.post { display: flex; flex-direction: column; width: 1720px; max-width: 100%; }

.post__head { display: flex; flex-direction: column; align-items: flex-start; }

.post__date {
  font-family: var(--en);
  font-weight: 500;
  font-size: 16px;
  line-height: 24px;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, 0.45);
}

.post__title {
  margin-top: 10px;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 36px;
  line-height: 1.4;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.post__rule {
  width: 413px;
  max-width: 100%;
  height: 0;
  margin: 22px 0 0;
  border: 0;
  border-top: 1px solid var(--red);
}

.post__body { margin-top: 44px; }

/* Newer on the left, older on the right, each a label over the title. */
.post__nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 32px;
  margin-top: 72px;
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}

.post__nav-cell--older { text-align: right; }

.post__nav-link { display: inline-flex; flex-direction: column; gap: 6px; max-width: 100%; }

.post__nav-label {
  font-family: var(--en);
  font-weight: 500;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.04em;
  color: rgba(0, 0, 0, 0.45);
}

.post__nav-title {
  font-family: var(--jp);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  transition: color 160ms ease;
}

.post__nav-link:hover .post__nav-title { color: var(--red); }

/* Back to the list. The site's one arrow glyph points right, so it is
   mirrored here rather than drawn a second time. */
.post__back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  margin-top: 40px;
  font-family: var(--jp);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

.post__back-icon { width: 20px; height: 20px; flex: none; transform: scaleX(-1); transition: transform 160ms ease; }
.post__back:hover { color: var(--red); }
.post__back:hover .post__back-icon { transform: scaleX(-1) translateX(3px); }

@media (max-width: 680px) {
  .post__title { font-size: 26px; line-height: 1.35; }
  .post__body { margin-top: 32px; }
  .post__nav { grid-template-columns: 1fr; gap: 20px; margin-top: 48px; }
  .post__nav-cell--older { text-align: left; }
}

/* The announcement pages' half of the selection rule above: the entry's
   number, date, title and arrow and the post count are chrome; its excerpt
   and the post's body are the copy someone came for. */
.feed__count,
.entry__no,
.entry__date,
.entry__title,
.post__date,
.post__nav,
.post__back {
  -webkit-user-select: none;
  user-select: none;
}
