/* ==========================================================================
   NORTHSAGA — WORKFLOW AND JOURNAL PAGES
   Loaded only by /agents/* and /journal/*. Everything here is built from the
   same devices as site.css: hairline rules, square corners, brass used for a
   figure or a label and nothing else. No value is hard-coded — see tokens.css.
   Order: page head → schematic → numbered lists → code → parts → media →
   price → paging → journal
   ========================================================================== */

/* ---------- Page head ----------
   Extra top padding so the h1 clears the fixed header on a short viewport. */
.work-head,
.article-head { padding-top: var(--space-7); }

.work-head h1,
.article-head h1 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--step-4);
  line-height: 1.02;
  letter-spacing: -0.005em;
  max-width: 16ch;
}

/* ==========================================================================
   SCHEMATICS
   Engineering drawing, not an illustration. Every colour is a class, never an
   attribute.

   The whole drawing is visible at rest on any screen: the stage is
   min(100%, its own width), so it fits a phone and is never blown up past
   full size on a desktop. That makes the type small on a narrow screen, which
   is what js/schematic.js pays for — it widens the stage past 100% and the
   viewport scrolls. Without JS you get the complete drawing and no zoom,
   which is the right thing to fail to.
   ========================================================================== */
.schematic { margin-top: var(--space-5); }

.schematic-viewport {
  overflow: auto;
  max-height: 78vh;
  -webkit-overflow-scrolling: touch;
  /* One finger scrolls; two fingers are handed to the pinch handler. */
  touch-action: pan-x pan-y;
}
.schematic-viewport:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.schematic[data-zoomed="true"] .schematic-viewport { cursor: grab; }
.schematic[data-zoomed="true"] .schematic-viewport:active { cursor: grabbing; }

.schematic-stage { width: min(100%, var(--sch-w)); }

/* site.css sets svg { max-width: 100% } for photographs and the mark. Here the
   stage owns the width and the drawing fills it. */
.schematic-stage svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: none;
}

/* ---------- Zoom controls, injected by js/schematic.js ---------- */
.schematic-controls {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-2);
}

.sch-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding-inline: 0.55rem;
  background: none;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.sch-btn:hover:not(:disabled) { border-color: var(--brass); color: var(--brass); }
.sch-btn:disabled { opacity: 0.35; cursor: default; }
.sch-btn--text {
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-size: var(--step--1);
}

.sch-level {
  min-width: 3.5rem;
  text-align: center;
  font-size: var(--step--1);
  color: var(--bone-dim);
  font-variant-numeric: tabular-nums;
}

.sch-hint {
  font-size: var(--step--1);
  color: var(--bone-dim);
  margin-left: auto;
  text-align: right;
}

.sch-box {
  fill: var(--ink-raised);
  stroke: var(--hairline-strong);
  stroke-width: 1;
}

/* ---------- Node glyphs ----------
   Drawn in tools/icons.py. Monochrome on purpose: brass is the only accent
   this brand has, so a wall of vendor colours would be a second palette.
   --cut must track .sch-box's fill or the punched-out detail stops reading. */
.sch-icon--fill { fill: var(--bone-dim); }
.sch-icon--cut  { fill: var(--ink-raised); }
.sch-icon--line {
  fill: none;
  stroke: var(--bone-dim);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sch-wire {
  fill: none;
  stroke: var(--brass);
  stroke-width: 1.25;
}
.sch-wire--dash { stroke-dasharray: 5 4; }

.sch-arrow { fill: var(--brass); stroke: none; }

.sch-role {
  font-family: var(--font-body);
  font-size: var(--sch-role);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  fill: var(--brass);
}

.sch-trigger {
  font-family: var(--font-body);
  font-size: var(--sch-trigger);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  fill: var(--brass);
  opacity: 0.72;
}

.sch-label {
  font-family: var(--font-body);
  font-size: var(--sch-label);
  fill: var(--bone);
}

.schematic figcaption {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--hairline);
  font-size: var(--step--1);
  color: var(--bone-dim);
  max-width: 62ch;
}
.sch-no {
  flex: none;
  color: var(--brass);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
}

/* ==========================================================================
   NUMBERED LISTS — the stages of a workflow, and the order it is built in.
   One component, two names, so a build step cannot drift out of the visual
   language the stages already established.
   ========================================================================== */
.stages,
.build-steps { margin-top: var(--space-4); }

.stages > li,
.build-steps > li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-1) var(--space-3);
  padding-block: var(--space-3);
  border-top: 1px solid var(--hairline);
}
.stages > li:last-child,
.build-steps > li:last-child { border-bottom: 1px solid var(--hairline); }

.stages .num,
.build-steps .num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.2;
  color: var(--brass);
  font-variant-numeric: tabular-nums;
}

.stages h3,
.build-steps h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-2);
  line-height: 1.2;
  margin-bottom: var(--space-1);
}

.stages p,
.build-steps p {
  color: var(--bone-dim);
  max-width: var(--measure);
}

.build-steps a { border-bottom: 1px solid var(--brass); }
.build-steps a:hover { color: var(--brass); }

/* Wide screens: heading left, body right, the same split .install-list uses. */
@media (min-width: 900px) {
  .stages > li > div,
  .build-steps > li > div {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
    gap: var(--space-4);
    align-items: start;
  }
  .stages h3,
  .build-steps h3 { margin-bottom: 0; }
}

/* ==========================================================================
   CODE — a command, a filename, a crontab line. Body font, because this is
   prose with a command in it rather than a terminal. No highlighting, no
   window chrome, no copy button.
   ========================================================================== */
code {
  font-family: var(--font-body);
  font-size: var(--step--1);
  color: var(--brass);
  background: var(--ink-raised);
  border-radius: var(--radius);
  padding: 0.12em 0.42em;
  white-space: nowrap;
}

.band--paper code {
  color: var(--brass-soft);
  background: var(--paper);
  border: 1px solid var(--hairline-light);
}

/* A value nobody has settled yet. Deliberately visible. Do not guess at one. */
.tbd {
  color: var(--brass);
  border-bottom: 1px dotted var(--brass);
  font-style: italic;
}
.band--paper .tbd {
  color: var(--brass-soft);
  border-bottom-color: var(--brass-soft);
}

/* ==========================================================================
   PARTS LIST — what it is built from, on the paper band
   ========================================================================== */
.parts-list { margin-top: var(--space-4); }
.parts-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1) var(--space-4);
  padding-block: var(--space-3);
  border-top: 1px solid var(--hairline-light);
}
.parts-list li:last-child { border-bottom: 1px solid var(--hairline-light); }
.parts-list h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-1);
  line-height: 1.2;
}
.parts-list p {
  color: var(--paper-ink-dim);
  max-width: 58ch;
}
@media (min-width: 820px) {
  .parts-list li { grid-template-columns: 1fr 1.6fr; }
}

/* ==========================================================================
   MEDIA — still a placeholder. The tag is pinned to the top-right corner, so
   the list needs room above it or the tag lands on the first heading.
   ========================================================================== */
.media-list { margin-top: var(--space-4); }
.media-list.is-placeholder { padding-top: calc(var(--space-3) + 1.2rem); }
.media-list li {
  padding-block: var(--space-3);
  border-top: 1px solid var(--hairline);
}
.media-list li:last-child { border-bottom: 1px solid var(--hairline); }
.media-list h3 {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: var(--space-1);
}
.media-list p { color: var(--bone-dim); max-width: 58ch; }

/* ==========================================================================
   PRICE — the ledger device, two rows, real numbers
   ========================================================================== */
.price-block {
  margin-top: var(--space-4);
  border-top: 2px solid var(--brass);
  max-width: 64ch;
}
.price-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--space-2);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--hairline);
}
.price-row .item strong {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-2);
  display: block;
  line-height: 1.2;
}
.price-row .item span {
  display: block;
  margin-top: 0.35rem;
  font-size: var(--step--1);
  color: var(--bone-dim);
  max-width: 46ch;
}
.price-row .figure {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--brass);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.price-row .figure small {
  display: block;
  text-align: right;
  font-family: var(--font-body);
  font-size: var(--step--1);
  color: var(--bone-dim);
  letter-spacing: 0.04em;
}

.price-note {
  margin-top: var(--space-3);
  font-size: var(--step--1);
  color: var(--bone-dim);
  max-width: 56ch;
}

/* ==========================================================================
   PAGING
   ========================================================================== */
.work-paging {
  padding-block: var(--space-4);
  border-top: 1px solid var(--hairline);
}
.work-paging-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  justify-content: space-between;
  align-items: baseline;
}
.work-paging a {
  font-family: var(--font-display);
  font-size: var(--step-1);
}
.work-paging a:hover { color: var(--brass); }
.work-paging a span {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: 0.35rem;
}
.work-paging .work-next { text-align: right; }
.work-paging .work-back {
  font-family: var(--font-body);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--bone-dim);
}

/* ==========================================================================
   JOURNAL
   The list is generated from assets/data/cron-jobs.json. Same devices again:
   the expression carried in a code element, the three questions as labelled
   rows, hairlines between entries.
   ========================================================================== */
.article-meta {
  margin-top: var(--space-3);
  font-size: var(--step--1);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--bone-dim);
}

.cron-list { margin-top: var(--space-4); }

.cron-entry {
  padding-block: var(--space-4);
  border-top: 1px solid var(--hairline);
}
.cron-entry:last-child { border-bottom: 1px solid var(--hairline); }

.cron-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-2);
}
.cron-head .num {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--brass);
  font-variant-numeric: tabular-nums;
}
.cron-head h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-2);
  line-height: 1.2;
  flex-basis: 100%;
}
.cron-expr { font-size: var(--step-0); }

.cron-body { margin-top: var(--space-2); }
.cron-body > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.25rem var(--space-3);
  padding-block: var(--space-1);
}
.cron-body dt {
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--brass);
}
.cron-body dd { color: var(--bone-dim); max-width: var(--measure); }

@media (min-width: 820px) {
  .cron-body > div { grid-template-columns: 15rem minmax(0, 1fr); }
}

/* .contact-lines was drawn for the paper band. The journal's closing section
   sits on --ink-deep, so it needs the dark hairline and the brighter brass. */
.article-contact { margin-top: var(--space-4); }
.article-contact li { border-bottom-color: var(--hairline); }
.article-contact .k { color: var(--brass); }

/* The one caveat worth printing next to a list of schedules. */
.cron-caveat {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--hairline);
  background: var(--ink-raised);
  max-width: 64ch;
}
.cron-caveat p { color: var(--bone-dim); font-size: var(--step--1); }
.cron-caveat p + p { margin-top: var(--space-1); }

/* ---------- Small screens ---------- */
@media (max-width: 640px) {
  /* Full-bleed the drawing out through the container gutter. On a 390px phone
     that is roughly 40px of extra width, which is 11% more drawing. */
  .schematic-viewport {
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--space-1);
  }
  /* Keep the hint — on a phone the drawing is at its smallest and the reader
     most needs telling that it zooms. It just gets its own line. */
  .schematic-controls { flex-wrap: wrap; }
  .sch-hint {
    margin-left: 0;
    flex-basis: 100%;
    text-align: left;
  }

  .price-row { grid-template-columns: 1fr; }
  .price-row .figure,
  .price-row .figure small { text-align: left; }
  .work-paging .work-next { text-align: left; }
  .stages > li,
  .build-steps > li { gap: var(--space-1) var(--space-2); }
}
