/* ============================================================
   ta-print-issues-v3.2.0.css
   INBXIFY T-A — Print Issues index · LAYOUT ONLY
   Companion: ta-print-issues-v3.2.0.js — independently versioned.

   THE THREE T-A HAZARDS APPLY HERE UNCHANGED. This surface sits
   inside section.publisher-wrapper like every other, so:

     (a) `section.publisher-wrapper *` forces background-color on
         EVERY descendant at (0,1,1) with !important — including a
         span inside a button. Every colour rule below is authored
         at (0,2,0)+ with !important and reaches its own children
         with a trailing `*` where it needs to.

     (b) ix-buttons sets `font-family: DM Sans !important` at
         (0,2,1) and loads after most sheets. Nothing here fights
         it — the parse button IS an ix-button and is left alone.

     (c) NEVER use a generic state class on T-A. `is-on`,
         `is-active`, `has-*` are owned elsewhere. Every class in
         this file is `tpi-` prefixed.

   Tokens only. No literal colours except the two rgba washes,
   which have no token and are documented where they appear.
   ============================================================ */

.tpi-root {
  font-family: var(--ix-font-body, 'DM Sans', system-ui, sans-serif);
}

/* ── Head ──────────────────────────────────────────────────── */
.tpi-root .tpi-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 0 0 11px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--ix-border, #E4E0D4);
}
.tpi-root .tpi-h2 {
  margin: 0 !important;
  font: 600 18px/1.15 var(--ix-font-display, 'Fraunces', Georgia, serif) !important;
  color: var(--ix-teal, #1A3A3A) !important;
}
.tpi-root .tpi-sub {
  font-size: 11.5px;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-sp { flex: 1; }

/* ── Parse strip ──
      The parser does not exist. This reads as a stated absence
      rather than a broken control: dashed edge, muted ground, the
      reason in the copy and on the disabled button. When
      PARSER_READY flips, .tpi-wait--off comes off and it becomes
      a live salmon-edged prompt. ───────────────────────────── */
.tpi-root .tpi-wait {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  margin-bottom: 14px;
  border-radius: 7px;
  border: 1px solid var(--ix-salmon, #EC7259);
  border-left-width: 4px;
  background: var(--ix-surface, #FFF) !important;
}
.tpi-root .tpi-wait--off {
  border-style: dashed;
  border-color: var(--ix-border-input, #DDD9C8);
  border-left-width: 1px;
  background: var(--ix-cream-warm, #FDFCF8) !important;
}
.tpi-root .tpi-wait-i {
  width: 30px; height: 38px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--ix-border-input, #DDD9C8);
  border-radius: 3px;
  font: 700 8px/1 var(--ix-font-mono, ui-monospace, monospace);
  letter-spacing: .06em;
  background: var(--ix-cream-deep, #F1EDE2) !important;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-wait-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tpi-root .tpi-wait-t b {
  font: 600 13px/1.2 var(--ix-font-body);
  color: var(--ix-text-dark, #1E2A3A) !important;
}
.tpi-root .tpi-wait-t em {
  font-style: normal; font-size: 10.5px; line-height: 1.4;
  color: var(--ix-text-light, #6B7280) !important;
}

/* ── The list ──────────────────────────────────────────────── */
.tpi-root .tpi-list { display: flex; flex-direction: column; gap: 9px; }

.tpi-root .tpi-row {
  display: flex;
  align-items: stretch;
  gap: 13px;
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--ix-border, #E4E0D4);
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  font-family: var(--ix-font-body);
  background: var(--ix-surface, #FFF) !important;
}
.tpi-root .tpi-row:hover {
  border-color: var(--ix-teal, #1A3A3A);
  box-shadow: 0 2px 8px rgba(26, 58, 58, .07);   /* teal at 7% — no token */
}

.tpi-root .tpi-cv {
  width: 52px;
  aspect-ratio: 17 / 22;                          /* a page, not a square */
  flex: none;
  border: 1px solid var(--ix-border-input, #DDD9C8);
  border-radius: 4px;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font: 700 7px/1 var(--ix-font-mono, ui-monospace, monospace);
  letter-spacing: .1em;
  background: var(--ix-cream-deep, #F1EDE2) !important;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-cv img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tpi-root .tpi-mid {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 3px; justify-content: center;
}
.tpi-root .tpi-nm {
  font: 600 15px/1.15 var(--ix-font-display, 'Fraunces', Georgia, serif);
  color: var(--ix-text-dark, #1E2A3A) !important;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* An unnamed issue falls back to its filename, and it LOOKS like a
   fallback. A value nobody set should never read as a value. */
.tpi-root .tpi-nm--unset {
  font-family: var(--ix-font-mono, ui-monospace, monospace);
  font-size: 12.5px;
  font-style: italic;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-meta {
  font: 500 9.5px/1.3 var(--ix-font-mono, ui-monospace, monospace);
  letter-spacing: .02em;
  color: var(--ix-text-light, #6B7280) !important;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Progress ──
      UNDECIDED leads. It is the only number that means work is
      outstanding; ALLOCATED supports it, and the bar carries the
      whole shape. ─────────────────────────────────────────── */
.tpi-root .tpi-prog { display: flex; align-items: center; gap: 14px; flex: none; }
.tpi-root .tpi-n {
  display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 46px;
}
.tpi-root .tpi-n b {
  font: 600 20px/1 var(--ix-font-display, 'Fraunces', Georgia, serif);
}
.tpi-root .tpi-n span {
  font: 700 7.5px/1 var(--ix-font-body);
  letter-spacing: .11em;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-n--open b { color: var(--ix-salmon-ink, #C0432B) !important; }
.tpi-root .tpi-n--done b { color: var(--ix-ok, #1F7A5C) !important; }
.tpi-root .tpi-n--mute b { color: var(--ix-text-light, #6B7280) !important; }

.tpi-root .tpi-bar {
  width: 96px; height: 7px; flex: none;
  border-radius: 4px; overflow: hidden; display: flex;
  background: var(--ix-cream-deep, #F1EDE2) !important;
}
.tpi-root .tpi-bar i { display: block; height: 100%; }
.tpi-root .tpi-b--al { background: var(--ix-teal, #1A3A3A) !important; }
.tpi-root .tpi-b--pk { background: var(--ix-gold, #C4A35A) !important; }
.tpi-root .tpi-b--dl { background: rgba(192, 57, 43, .45) !important; }   /* danger @45% */
.tpi-root .tpi-b--un { background: var(--ix-salmon-soft, rgba(236,114,89,.14)) !important; }

.tpi-root .tpi-st {
  align-self: center; flex: none; white-space: nowrap;
  padding: 3px 9px; border-radius: 10px;
  font: 700 8px/1.3 var(--ix-font-body);
  letter-spacing: .1em; text-transform: uppercase;
}
.tpi-root .tpi-st--open,
.tpi-root .tpi-st--open * {
  background: var(--ix-salmon-soft, rgba(236,114,89,.14)) !important;
  color: var(--ix-salmon-ink, #C0432B) !important;
}
.tpi-root .tpi-st--done,
.tpi-root .tpi-st--done * {
  background: rgba(31, 122, 92, .13) !important;                          /* ok @13% */
  color: var(--ix-ok, #1F7A5C) !important;
}
.tpi-root .tpi-chev {
  align-self: center; flex: none;
  font-size: 15px;
  color: var(--ix-text-light, #6B7280) !important;
}

/* ── Empty ─────────────────────────────────────────────────── */
.tpi-root .tpi-none {
  padding: 28px; text-align: center; line-height: 1.6; font-size: 12px;
  border: 1px dashed var(--ix-border-input, #DDD9C8);
  border-radius: 8px;
  background: transparent !important;
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-none em { display: block; margin-top: 4px; font-style: normal; font-size: 11px; }

/* ── Breadcrumb ──
      Shown INSTEAD of the list once an issue is picked. The board
      renders below it in its own host, so this is the only thing
      standing between the operator and a way back. ─────────── */
.tpi-root .tpi-crumb {
  display: flex; align-items: baseline; gap: 11px;
  padding: 0 0 10px; margin-bottom: 12px;
  border-bottom: 1px solid var(--ix-border, #E4E0D4);
}
.tpi-root .tpi-back {
  border: 1px solid var(--ix-border-input, #DDD9C8);
  border-radius: 6px;
  padding: 5px 11px;
  cursor: pointer;
  font: 600 11.5px/1.3 var(--ix-font-body);
  background: var(--ix-surface, #FFF) !important;
  color: var(--ix-teal, #1A3A3A) !important;
}
.tpi-root .tpi-back:hover { border-color: var(--ix-teal, #1A3A3A); }
.tpi-root .tpi-crumb-n {
  font: 600 15px/1.15 var(--ix-font-display, 'Fraunces', Georgia, serif);
  color: var(--ix-text-dark, #1E2A3A) !important;
}
.tpi-root .tpi-crumb-m {
  font: 500 9.5px/1.3 var(--ix-font-mono, ui-monospace, monospace);
  color: var(--ix-text-light, #6B7280) !important;
}

@media (max-width: 900px) {
  /* The progress block is the first thing to go — the status pill
     and the counts survive, which is what the row is for. */
  .tpi-root .tpi-bar { display: none; }
  .tpi-root .tpi-prog { gap: 10px; }
}


/* ════════════════════════════════════════════════════════════
   §2 · THE YEAR CALENDAR  (v2.0.0)
   ────────────────────────────────────────────────────────────
   v1 listed issues that existed. v2 lists issues that are
   EXPECTED, most of which are empty. Empty is the default
   state and it must look like one.

   THE ELEMENT-TYPE TRAP, and why it is fixed here rather than
   patched later. A filled slot is a <button> and an empty one
   is a <div>. A button centres its text and carries its own
   font by UA default, so a filled row sat centred while every
   empty row sat left. A row must not change shape because of
   which element it happens to be, so `.tpi-sl` declares
   text-align, font, width and colour explicitly and both types
   inherit from the same baseline. Any row type added later —
   uploading, failed — starts correct.
   ──────────────────────────────────────────────────────── */

/* One baseline for every row type. */
.tpi-root .tpi-sl {
  display: flex;
  align-items: stretch;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--ix-border, #E4E0D4);
  border-radius: 8px;
  text-align: left;
  font-family: var(--ix-font-body);
  color: inherit;
  background: var(--ix-surface, #FFF) !important;
}
.tpi-root .tpi-sl .tpi-mid,
.tpi-root .tpi-sl .tpi-mn,
.tpi-root .tpi-sl .tpi-meta { text-align: left; }

/* Empty reads as absence: no ground, dashed edge. */
.tpi-root .tpi-sl--empty {
  border-style: dashed;
  border-color: var(--ix-border-input, #DDD9C8);
  background: transparent !important;
}
.tpi-root .tpi-sl--empty .tpi-mn { color: var(--ix-text-light, #6B7280) !important; }
.tpi-root .tpi-sl--empty .tpi-cv {
  border-style: dashed;
  background: transparent !important;
}
.tpi-root .tpi-sl--future { opacity: .5; }

.tpi-root .tpi-sl--parsed { cursor: pointer; }
.tpi-root .tpi-sl--parsed:hover {
  border-color: var(--ix-teal, #1A3A3A);
  box-shadow: 0 2px 8px rgba(26, 58, 58, .07);
}

/* Slightly tighter than v1 — twelve rows, not three. */
.tpi-root .tpi-list { gap: 7px; }
.tpi-root .tpi-cv { width: 44px; font-size: 6.5px; }
.tpi-root .tpi-mn { font-size: 14px; }
.tpi-root .tpi-n b { font-size: 18px; }
.tpi-root .tpi-bar { width: 84px; height: 6px; }
.tpi-root .tpi-act { align-self: center; flex: none; }

/* ── Head ─────────────────────────────────────────────────── */
.tpi-root .tpi-head { flex-wrap: wrap; align-items: center; }
.tpi-root .tpi-freq {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--ix-border-input, #DDD9C8);
  border-radius: 20px; padding: 4px 11px;
  font: 500 10.5px/1.3 var(--ix-font-body);
  background: var(--ix-surface, #FFF) !important;
  color: var(--ix-text-mid, #5A6478) !important;
}
.tpi-root .tpi-freq b { font-weight: 700; color: var(--ix-teal, #1A3A3A) !important; }
/* A frequency nobody set must not read as one somebody did. */
.tpi-root .tpi-freq em {
  font-style: normal; font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ix-salmon-ink, #C0432B) !important;
}

.tpi-root .tpi-reveal { display: inline-flex; align-items: center; gap: 7px; }
.tpi-root .tpi-hid {
  font: 500 9.5px/1.3 var(--ix-font-mono, ui-monospace, monospace);
  color: var(--ix-text-light, #6B7280) !important;
}
.tpi-root .tpi-rv { padding: 4px 10px !important; font-size: 10.5px !important; }

.tpi-root .tpi-yr { display: inline-flex; align-items: center; gap: 2px; }
.tpi-root .tpi-yb {
  border: 1px solid var(--ix-border-input, #DDD9C8);
  padding: 5px 11px; cursor: pointer;
  font: 600 11.5px/1.3 var(--ix-font-body);
  background: var(--ix-surface, #FFF) !important;
  color: var(--ix-text-mid, #5A6478) !important;
}
.tpi-root .tpi-yb:first-child { border-radius: 6px 0 0 6px; }
.tpi-root .tpi-yb:last-child  { border-radius: 0 6px 6px 0; }
.tpi-root .tpi-yb--on,
.tpi-root .tpi-yb--on * {
  border-color: var(--ix-teal, #1A3A3A);
  background: var(--ix-teal, #1A3A3A) !important;
  color: var(--ix-rail-text-on, #FFF) !important;
  font-weight: 700;
}

.tpi-root .tpi-st--none,
.tpi-root .tpi-st--none * {
  background: var(--ix-cream-deep, #F1EDE2) !important;
  color: var(--ix-text-light, #6B7280) !important;
}

/* ── Off-calendar ──
      A parsed issue whose name matches no slot. Shown, never
      dropped — a rename or a typo must not make an issue
      disappear. ─────────────────────────────────────────── */
.tpi-root .tpi-orph {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--ix-border, #E4E0D4);
  display: flex; flex-direction: column; gap: 7px;
}
.tpi-root .tpi-orph-h {
  font: 700 9px/1.3 var(--ix-font-body);
  text-transform: uppercase; letter-spacing: .11em;
  color: var(--ix-salmon-ink, #C0432B) !important;
}
.tpi-root .tpi-orph-w {
  font-size: 10.5px; line-height: 1.45; margin-bottom: 2px;
  color: var(--ix-text-light, #6B7280) !important;
}


/* ════════════════════════════════════════════════════════════
   §3 · THE PLAN  (v3.0.0)
   ────────────────────────────────────────────────────────────
   v2 derived the year from a frequency. v3 reads a stored
   schedule, so the only visual change is the head pill (a
   count, not a rate) and one new state: no plan set.

   A MISSING SCHEDULE IS A STATED ABSENCE. It names the field
   and shows the shape the value takes, because the next thing
   the operator does is go and write one. An empty page would
   make them guess.
   ──────────────────────────────────────────────────────── */

.tpi-root .tpi-noplan {
  display: flex; flex-direction: column; gap: 9px;
  padding: 22px 24px;
  border: 1px dashed var(--ix-border-input, #DDD9C8);
  border-radius: 8px;
  background: var(--ix-cream-warm, #FDFCF8) !important;
}
.tpi-root .tpi-noplan b {
  font: 600 15px/1.3 var(--ix-font-display, 'Fraunces', Georgia, serif);
  color: var(--ix-text-dark, #1E2A3A) !important;
}
.tpi-root .tpi-noplan span {
  font-size: 11.5px; line-height: 1.6; max-width: 640px;
  color: var(--ix-text-mid, #5A6478) !important;
}
.tpi-root .tpi-noplan code {
  border-radius: 3px; padding: 1px 5px;
  font: 11px var(--ix-font-mono, ui-monospace, monospace);
  background: var(--ix-cream-deep, #F1EDE2) !important;
  color: var(--ix-text-dark, #1E2A3A) !important;
}
.tpi-root .tpi-noplan pre {
  margin: 2px 0 0; padding: 11px 13px; overflow-x: auto;
  border: 1px solid var(--ix-border-soft, #EEE9DC);
  border-radius: 6px;
  font: 11px/1.6 var(--ix-font-mono, ui-monospace, monospace);
  background: var(--ix-surface, #FFF) !important;
  color: var(--ix-text-dark, #1E2A3A) !important;
}


/* ════════════════════════════════════════════════════════════
   §4 · THE CANONICAL HEADER TAKES OVER  (v3.2.0)
   ────────────────────────────────────────────────────────────
   Row 1 is now IxHeader.render() and the refresh is
   IxHeader.refreshBtn(). ix-header owns the icon disc, the
   title, the subtitle and the whole refresh control — size,
   border, hover and .is-spinning — so none of that is authored
   here any more.

   WHAT REMAINS is only what ix-header does not know about: the
   planned-issue count, the parsed count and the reveal control,
   which ride in the header's `actions` slot.

   .tpi-head SURVIVES as the fallback shape. §1 styles it and it
   renders when ix-header is absent, which must degrade to a
   plain title rather than nothing.
   ──────────────────────────────────────────────────────── */

/* The three things that ride in the actions slot. They sit
   beside the refresh control, so they inherit its row and only
   need their own type. */
.tpi-root .ix-hdr-right .tpi-freq,
.tpi-root .ix-hdr-right .tpi-sub,
.tpi-root .ix-hdr-right .tpi-reveal { align-self: center; }

.tpi-root .ix-hdr-right { gap: 10px; flex-wrap: wrap; }

/* Year tabs are IxTabs.l1 now — ix-header styles the row and the
   buttons. The old .tpi-yb rules stay for the no-ix-header
   fallback and are not used otherwise. */
.tpi-root .ix-tabs-l1 { margin-bottom: 12px; }
