/* ============================================================
   Case study detail — the project record as a readable page
   Follows the equipment page's grammar: alternating white /
   light-grey sections, the shared section head, a fact strip
   with a blue top edge, cards and numbered ladder rows. The
   verified stage travels as a blue text chip — never a medal
   (DESIGN.md §10 案例和项目阶段). Local prefix: nz-cs-.
   ============================================================ */

.nz-cs-section {
  padding: 96px 0;
  background: var(--white);
}

.nz-cs-section--soft {
  background: var(--gray-bg);
}

/* A band that stands on a photograph (--ground). The picture arrives from the
   record as --nz-cs-ground and is painted as a SECOND background layer of the
   section itself, under a flat veil of the band's own grey.

   Why a layered background and not a ::before overlay: the verification band
   carries a sticky stage index in its right-hand rail. `position: sticky` is
   broken by any scrolling ancestor, so `overflow: hidden` — and any pseudo
   element that needs it to stay inside the band — silently stops the rail from
   floating. A background layer creates no box, no stacking context and no
   scroll container, so the sticky rail keeps working on every record that sets
   a picture, not only this one. The veil is one flat colour because only the
   two layers are needed: band grey (#F4F6F8, 0.94) over the photo, which is the
   same weight as a 6% photograph, and the band's text stays at full contrast. */

.nz-cs-section--ground {
  background-color: var(--gray-bg);
  background-image:
    linear-gradient(rgba(244, 246, 248, 0.94), rgba(244, 246, 248, 0.94)),
    var(--nz-cs-ground);
  background-position: center, center;
  background-size: cover, cover;
  background-repeat: no-repeat, no-repeat;
}

@media (prefers-contrast: more) {
  .nz-cs-section--ground {
    background-image:
      linear-gradient(rgba(244, 246, 248, 0.98), rgba(244, 246, 248, 0.98)),
      var(--nz-cs-ground);
  }
}

.nz-cs-head {
  margin-bottom: 42px;
}

.nz-cs-head .section-heading {
  margin-bottom: 0;
}

.nz-cs-head .section-heading__copy h2 {
  max-width: 26ch;
  margin-bottom: 0;
}

/* ---- Prose blocks inside cards ---- */
.nz-cs-prose {
  color: var(--gray-text);
  font-size: 15px;
  line-height: 1.7;
}

.nz-cs-prose > *:last-child {
  margin-bottom: 0;
}

.nz-cs-prose p + p {
  margin-top: 10px;
}

.nz-cs-prose ul,
.nz-cs-prose ol {
  max-width: 72ch;
  padding-left: 22px;
}

.nz-cs-prose li {
  margin-bottom: 8px;
}

.nz-cs-subhead {
  margin: 0 0 12px;
  color: var(--blue);
  font-size: 1.05rem;
  font-weight: 700;
}

@media (max-width: 940px) {
  .nz-cs-head {
    margin-bottom: 30px;
  }
}

@media (max-width: 900px) {
  .nz-cs-section {
    padding: 68px 0;
  }
}

@media (max-width: 650px) {
  .nz-cs-section {
    padding: 52px 0;
  }
}

/* ---- The tag strip under the page header ----
   The stage, date, application, place and identity now travel in the header's
   right-hand column (framework.css: .nz-page-head--split), so this band carries
   the taxonomy chips alone and no longer needs the gap the fact card wanted. */
.nz-cs-strip {
  padding: 32px 0 56px;
  background: var(--white);
}

.nz-cs-strip .nz-single__meta {
  margin-bottom: 0;
}


/* The verified stage as a blue text chip — the same family the
   home page's case cards use, never a green medal. */
.nz-cs-stagechip {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid var(--blue);
  border-radius: 999px;
  color: var(--blue);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* ---- The situation: the goal first, then the condition cards ---- */
.nz-cs-goal {
  max-width: 780px;
  margin-bottom: 22px;
  padding: 24px 28px;
  border: 1px solid var(--gray-line);
  border-top: 3px solid var(--blue);
  border-radius: var(--radius);
  background: var(--white);
}

.nz-cs-goal .nz-cs-prose {
  color: var(--text);
  font-size: 1.05rem;
}

.nz-cs-sitcards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.nz-cs-sitcard {
  padding: 22px 26px;
  border: 1px solid var(--gray-line);
  border-radius: var(--radius);
  background: var(--white);
}

@media (max-width: 760px) {
  .nz-cs-sitcards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- What was delivered: reason cards, then the scope rows ---- */
.nz-cs-why {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-bottom: 44px;
}

.nz-cs-whycard {
  padding: 22px 26px;
  border: 1px solid var(--gray-line);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  background: var(--white);
}

.nz-cs-why .nz-cs-whycard:only-child {
  grid-column: 1 / -1;
}

@media (max-width: 760px) {
  .nz-cs-why {
    grid-template-columns: minmax(0, 1fr);
    margin-bottom: 32px;
  }
}

.nz-cs-scopehead {
  margin-bottom: 6px;
}

.nz-cs-scope {
  margin: 0;
  padding: 0;
  list-style: none;
}

.nz-cs-scoperow {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr) auto;
  gap: 8px 32px;
  align-items: start;
  padding: 20px 0;
  border-top: 1px solid var(--gray-line);
}

.nz-cs-scoperow:first-child {
  border-top: 0;
}

.nz-cs-typechip {
  display: inline-block;
  padding: 2px 9px;
  border: 1px solid var(--gray-line);
  border-radius: 999px;
  color: var(--gray-text);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.nz-cs-scoperow__what {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 14px;
  align-items: baseline;
}

.nz-cs-scoperow__name {
  font-size: 16.5px;
  font-weight: 600;
}

.nz-cs-scoperow__name a {
  color: var(--blue);
}

.nz-cs-scoperow__config {
  grid-column: 2;
  color: var(--gray-text);
  font-size: 13.5px;
  line-height: 1.55;
}

.nz-cs-scoperow__role p {
  margin: 0;
  color: var(--gray-text);
  font-size: 14px;
  line-height: 1.6;
}

.nz-cs-scoperow__note {
  color: var(--gray-text);
  font-size: 13px;
  font-style: italic;
}

.nz-cs-scoperow__qty {
  padding-top: 3px;
  color: var(--text);
  font-size: 13.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 760px) {
  .nz-cs-scoperow {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }

  .nz-cs-scoperow__qty {
    padding-top: 0;
  }
}

/* ---- Verified stages: the numbered ladder, blue family ----
   The band is a three-area grid — head, ladder, side rail. The rail holds the
   note that explains the ladder and a clickable index of the stages, so the
   right half works instead of standing empty, and it sticks while the ladder
   is read. Below 1080px the three areas stack in reading order: head, note and
   index, ladder. */
.nz-cs-verify {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  grid-template-areas:
    "head aside"
    "list aside";
  column-gap: 64px;
  align-items: start;
}

.nz-cs-verify__head {
  grid-area: head;
}

/* The rail sticks under the pinned site stack, not under the bare viewport
   edge. The stack is the blue utility bar plus the 80px header and measures
   126px while it is pinned — the same number site.css already uses for
   scroll-padding-top — so the offset is that height plus a 16px breather. The
   earlier 88px put the top of the card under the navigation, where its first
   line was hidden. On a phone the rail is not sticky at all (it stacks below
   1080px), so no second height has to be kept in sync here. */
.nz-cs-verify__aside {
  grid-area: aside;
  position: sticky;
  top: calc(126px + 16px);
  padding: 22px 24px 20px;
  border: 1px solid var(--gray-line);
  border-top: 2px solid var(--blue);
  border-radius: var(--radius);
  background: var(--white);
}

/* A logged-in editor carries WordPress's fixed admin bar above the stack, so the
   stack is that much taller and the rail has to start below it too. Visitors get
   the 0px fallback and the plain offset. */
body.admin-bar .nz-cs-verify__aside {
  top: calc(126px + 16px + var(--wp-admin--admin-bar--height, 32px));
}

.nz-cs-verify__note {
  margin: 0;
  color: var(--gray-text);
  font-size: 13.5px;
  line-height: 1.65;
}

.nz-cs-verify__index {
  margin: 16px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--gray-line);
  list-style: none;
}

.nz-cs-verify__item a {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 6px 0;
  color: var(--gray-text);
  font-size: 14px;
  text-decoration: none;
}

.nz-cs-verify__item a:hover,
.nz-cs-verify__item a:focus-visible {
  color: var(--blue);
}

.nz-cs-verify__num {
  flex: 0 0 auto;
  color: var(--blue);
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.nz-cs-verify__item--current a {
  color: var(--blue);
  font-weight: 600;
}

.nz-cs-stages {
  grid-area: list;
  max-width: 860px;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (max-width: 1080px) {
  .nz-cs-verify {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "head"
      "aside"
      "list";
    row-gap: 28px;
  }

  .nz-cs-verify__aside {
    position: static;
  }
}

/* An index link lands a stage under the pinned stack, so the landing offset is
   the same 126px stack height plus the same 16px breather as the rail above;
   96px left the stage heading tucked under the navigation. */
.nz-cs-stagerow {
  scroll-margin-top: calc(126px + 16px);
  display: flex;
  gap: 20px;
  padding: 22px 0;
  border-top: 1px solid var(--gray-line);
}

.nz-cs-stagerow:first-child {
  border-top: 0;
}

.nz-cs-stagerow__num {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  background: var(--blue);
  color: var(--white);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.nz-cs-stagerow__label {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 0 0 8px;
  color: var(--blue);
  font-size: 16px;
  font-weight: 700;
}

.nz-cs-stagerow__body {
  max-width: 68ch;
}

.nz-cs-stagerow__body .nz-cs-prose {
  color: var(--gray-text);
  font-size: 14.5px;
}

/* ---- Results: figures only ever with their method ---- */
.nz-cs-results {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.nz-cs-result {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px 28px;
  border: 1px solid var(--gray-line);
  border-top: 3px solid var(--blue);
  border-radius: var(--radius);
  background: var(--white);
}

.nz-cs-result__metric {
  margin: 0;
  font-size: 17px;
}

.nz-cs-result__figures {
  display: flex;
  gap: 12px;
  align-items: baseline;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.nz-cs-result__before {
  color: var(--gray-text);
  font-size: 1.35rem;
}

.nz-cs-result__arrow {
  color: var(--gray-text);
}

.nz-cs-result__after {
  color: var(--blue);
  font-size: 1.7rem;
  font-weight: 700;
}

.nz-cs-result__unit {
  margin: -6px 0 0;
  color: var(--gray-text);
  font-size: 13px;
  line-height: 1.5;
}

.nz-cs-result__evidence {
  display: flex;
  gap: 10px;
  align-items: center;
  margin: 0;
}

.nz-cs-result__evidence-label {
  color: var(--gray-text);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.nz-cs-result__meta {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 2px 0 0;
  border-top: 1px solid var(--gray-line);
}

.nz-cs-result__metarow {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: 4px 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--gray-line);
}

.nz-cs-result__metarow:last-child {
  border-bottom: 0;
}

.nz-cs-result__metarow dt {
  color: var(--gray-text);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.nz-cs-result__metarow dd {
  margin: 0;
  color: var(--text);
  font-size: 13.5px;
  line-height: 1.55;
}

.nz-cs-result__file {
  display: grid;
  gap: 4px;
  margin: 0;
}

.nz-cs-result__file .text-link {
  justify-self: start;
}

.nz-cs-result__filenote {
  color: var(--gray-text);
  font-size: 12.5px;
}

@media (max-width: 860px) {
  .nz-cs-results {
    grid-template-columns: minmax(0, 1fr);
  }

  .nz-cs-result__metarow {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
}

/* ---- The opening: featured picture beside the record's own text ----
   The picture used to be a band of its own on a 16:9 frame at full container
   width — a screen tall, and letterboxed on both sides whenever the upload was
   4:3 — with the intro floating beneath it and the right half of the page empty.
   Now the two share one module: the picture is cropped to a composed 3:2 column
   and the intro reads in the column beside it. A record with only one of the two
   takes the full width in a single column. */
.nz-cs-opener {
  padding: 4px 0 24px;
  background: var(--white);
}

.nz-cs-opener__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  gap: 44px 56px;
  align-items: start;
}

.nz-cs-opener__grid--single {
  grid-template-columns: minmax(0, 1fr);
}

.nz-cs-opener__figures {
  display: grid;
  gap: 16px;
}

.nz-cs-opener__figure {
  margin: 0;
}

/* The opener prints every upload whole: the picture keeps its own proportions,
   so nothing is cut off at the top or the bottom. The frame used to be a fixed
   3:2 (21:9 for a single picture, 16:9 in the pair) with the overflow cropped,
   which silently cut tall subjects — a silo column, a gantry, a person — and
   made a wide upload shorter than the intro beside it. Height follows the file
   now, so a landscape upload lands near the prose's height on its own and a
   portrait one is shown in full rather than sliced. */
.nz-cs-opener__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  background: var(--gray-bg);
}

.nz-cs-opener__cap {
  display: block;
  padding-top: 10px;
  color: var(--gray-text);
  font-size: 12.5px;
  line-height: 1.5;
}

/* The intro keeps the article's reading treatment — one column, article type
   scale — but is capped so it reads at ~68 characters beside the picture
   instead of running the full container width. */
.nz-cs-opener__prose {
  max-width: 640px;
  color: var(--gray-text);
  font-size: 16.5px;
  line-height: 1.75;
}

.nz-cs-opener__prose > *:first-child {
  margin-top: 0;
}

.nz-cs-opener__prose > *:last-child {
  margin-bottom: 0;
}

.nz-cs-opener__prose p + p {
  margin-top: 1.15em;
}

.nz-cs-opener__prose h2 {
  margin: 2.2em 0 0.5em;
  color: var(--text);
  font-size: 19px;
  line-height: 1.4;
}

.nz-cs-opener__prose h3 {
  margin: 1.8em 0 0.4em;
  color: var(--text);
  font-size: 17px;
  line-height: 1.4;
}

.nz-cs-opener__prose a {
  color: var(--blue);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.nz-cs-opener__prose img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
}

.nz-cs-opener__prose blockquote {
  margin: 1.6em 0 0;
  padding: 4px 0 4px 20px;
  border-left: 3px solid var(--green);
  color: var(--gray-text);
}

.nz-cs-opener__prose blockquote p {
  margin: 0;
}

/* Under 1080 px the two columns stack: the picture keeps its composed frame at
   the top of the module and the text follows at a comfortable measure. */
@media (max-width: 1080px) {
  .nz-cs-opener__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  /* The picture is not re-framed when the columns stack: it still prints whole,
     only narrower. */
  .nz-cs-opener__figure img {
    height: auto;
  }

  .nz-cs-opener__prose {
    max-width: 68ch;
  }
}

/* A record with no picture: the text still opens the page under the tag strip.
   The strip carries 56px of its own bottom edge, so the opener adds only what
   brings the gap to the section rhythm. A record with neither a picture nor an
   intro has no opener at all, and the section that follows takes the same
   reduced top edge instead of leaving the strip's space doubled. */
.nz-cs-strip + .nz-cs-opener {
  padding-top: 8px;
}

.nz-cs-strip + .nz-cs-section,
.nz-cs-opener + .nz-cs-section {
  padding-top: 56px;
}

/* ---- Pictures, videos and records ----
   Six tiles to a row, whatever the record holds. The six tracks are declared
   whether or not six pictures arrive, so a row of four keeps four tiles of the
   six-to-a-row size and leaves the last two tracks empty instead of spreading
   the four across the full width; a seventh picture starts a second row of the
   same size again. */
.nz-cs-media {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nz-cs-media__item {
  margin: 0;
}

.nz-cs-media__link {
  display: block;
}

/* Every frame in the grid is the same size, so a project's evidence reads as one
   grid of pictures instead of a ragged row of different heights. The file keeps
   its own proportions inside that frame and is cropped to fill it (object-fit:
   cover), which is why the frame is square: the records carry wide workshop
   shots (4:3 and 16:9) alongside tall ones of a machine or a silo, and a square
   trims the least from either. The whole picture is shown at its own size once
   it is opened, in the lightbox (framework.css: .nz-lightbox__img keeps width
   and height auto), so nothing is lost — only the thumbnail is cropped. */
.nz-cs-media__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: center;
  border: 1px solid var(--gray-line);
  border-radius: var(--radius);
  background: var(--gray-bg);
}

/* Narrower windows step the count down rather than shrinking the six hundred
   and nothing: six tiles at phone width would be unreadable. The size stays
   equal inside each step, and an unfilled row still keeps its own size. */
@media (max-width: 1180px) {
  .nz-cs-media {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (max-width: 860px) {
  .nz-cs-media {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .nz-cs-media {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.nz-cs-videos {
  margin-top: 36px;
}

.nz-cs-videos__list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nz-cs-videos__item .text-link {
  justify-self: start;
}

.nz-cs-videos__plain {
  color: var(--gray-text);
  font-size: 14.5px;
}

.nz-cs-records {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 36px;
}

.nz-cs-files {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nz-cs-files .text-link {
  justify-self: start;
}

@media (max-width: 760px) {
  .nz-cs-records {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The related-records block sits in its own soft section; keep its
   internal spacing from doubling against the section padding. */
.nz-cs-section .nz-related {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* ---- Further details: the field list and the picture beside it ----------
   The band prints a short field list, so a record that carries one or two
   fields ended in a wide white area on the right. When the record names a
   picture (更多细节图片 / details_photo) the band becomes one two-column block:
   the heading and the field list stack on the left, and the picture occupies
   the whole right column — top edge level with the eyebrow, bottom edge level
   with the last field. Stretching the picture to the block is what removes the
   lopsided look of a tall text column beside a shorter image; it fills its
   frame by cropping, never by distorting. A record without a picture keeps the
   unchanged single column, so no space stands empty for a file that never
   arrived. */
.nz-cs-details {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.nz-cs-details__head,
.nz-cs-details__body {
  min-width: 0;
}

.nz-cs-details--media {
  grid-template-columns: minmax(0, 1fr) minmax(300px, 40%);
  grid-template-areas:
    "head figure"
    "body figure";
  column-gap: clamp(32px, 4vw, 64px);
  row-gap: 0;
  align-items: stretch;
}

.nz-cs-details--media .nz-cs-details__head {
  grid-area: head;
  align-self: start;
}

.nz-cs-details--media .nz-cs-details__body {
  grid-area: body;
  align-self: start;
}

/* The heading keeps the 50px that separates it from the fields; the list's own
   40px top margin would double that gap inside the two-column block. */
.nz-cs-details--media .nz-spec {
  margin-top: 0;
  max-width: none;
}

.nz-cs-details--media .nz-cs-details__figure {
  grid-area: figure;
  display: flex;
  flex-direction: column;
  align-self: stretch;
  min-height: 0;
  max-height: 560px;
  margin: 0;
}

.nz-cs-details__frame {
  position: relative;
  flex: 1 1 auto;
  min-height: 260px;
  overflow: hidden;
  border: 1px solid var(--gray-line);
  border-radius: var(--radius);
  background: var(--gray-bg);
}

/* The picture is positioned into the frame so it can follow the frame's height
   without touching the file's own proportions: object-fit crops the overflow. */
.nz-cs-details__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.nz-cs-details__cap {
  display: block;
  padding-top: 10px;
  color: var(--gray-text);
  font-size: 12.5px;
  line-height: 1.5;
}

/* Below 1080 px the picture moves under the fields at the same measure and
   returns to its own 4:3 frame, since there is no column left to balance. */
@media (max-width: 1080px) {
  .nz-cs-details--media {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "head"
      "body"
      "figure";
    column-gap: 0;
  }

  .nz-cs-details--media .nz-spec {
    margin-top: 32px;
    max-width: 980px;
  }

  .nz-cs-details--media .nz-cs-details__figure {
    max-width: 640px;
    max-height: none;
    margin-top: 32px;
  }

  .nz-cs-details__frame {
    flex: 0 0 auto;
    min-height: 0;
    aspect-ratio: 4 / 3;
  }
}
