// ripgrow session sheet — technical-drawing feel. Dense enough to read
// from the floor mid-lift, with the load number given the most weight.
//
// Layout: masthead across the top with title + profile + date; a warmup
// call-out band; a wide bordered table where each row is a slot with big
// numeric SETS / REPS / LOAD columns.
//
// Invoked as `typst compile --input data-path=data.json sheet.typ out.pdf`.
// Data schema: see pdf.rs render_json.

#let data = json(sys.inputs.at("data-path"))

#set page(paper: "us-letter", margin: (top: 0.55in, bottom: 0.55in, x: 0.55in))
#set text(font: "Helvetica", size: 11pt)

#let rule-heavy = 1.5pt
#let rule-light = 0.4pt
#let ink = rgb("#0f0f0f")
#let dim = rgb("#585858")
#let band = luma(238)

// -- masthead ---------------------------------------------------------------
#grid(
  columns: (1fr, auto),
  align: (left + bottom, right + bottom),
  [
    #text(size: 26pt, weight: "black", tracking: 3pt, fill: ink)[RIPGROW]
    #v(-0.35em)
    #text(size: 8pt, tracking: 2pt, fill: dim)[SESSION SHEET / TRAINING PROGRAM]
  ],
  [
    #text(size: 12pt, weight: "bold", tracking: 1pt, fill: ink)[#upper(data.profile)]
    #v(-0.35em)
    #text(size: 10pt, tracking: 1pt, fill: dim)[#data.date]
  ]
)

#v(0.25em)
#line(length: 100%, stroke: rule-heavy + ink)
#v(0.6em)

// -- warmup band ------------------------------------------------------------
#block(
  fill: band,
  inset: (x: 10pt, y: 8pt),
  width: 100%,
)[
  #grid(
    columns: (auto, 1fr),
    align: (left + horizon, left + horizon),
    column-gutter: 14pt,
    [
      #text(size: 8pt, weight: "bold", tracking: 2pt, fill: dim)[WARMUP]
    ],
    [
      #text(size: 12pt, weight: "medium", fill: ink)[
        #if data.warmup.len() > 0 [
          #data.warmup.join("   •   ")
        ] else [
          —
        ]
      ]
    ],
  )
]

#v(0.6em)

// -- main table -------------------------------------------------------------
//
// Columns: #, exercise, sets, reps, load, unit, vs. Rules are heavy at the
// top and bottom, light between rows. LOAD gets the largest type since that
// is what the lifter checks between working sets.

#let header-cell(body) = text(
  size: 8pt,
  weight: "bold",
  tracking: 2pt,
  fill: dim,
)[#body]

#let idx-cell(body) = text(size: 16pt, weight: "bold", fill: ink)[#body]
#let name-cell(body) = text(size: 15pt, weight: "medium", fill: ink)[#body]
#let num-cell(body) = text(size: 16pt, weight: "medium", fill: ink)[#body]
#let load-cell(body) = text(size: 18pt, weight: "bold", fill: ink)[#body]
#let unit-cell(body) = text(size: 10pt, weight: "medium", tracking: 1pt, fill: dim)[#body]
#let vs-cell(body) = text(size: 9pt, tracking: 1pt, fill: dim)[#upper(body)]

#table(
  columns: (28pt, 1fr, 44pt, 44pt, 84pt, 44pt, 52pt),
  align: (center + horizon, left + horizon, right + horizon, right + horizon, right + horizon, left + horizon, right + horizon),
  stroke: (x, y) => (
    top: if y == 0 { rule-heavy + ink }
         else if y == 1 { rule-heavy + ink }
         else { rule-light + dim },
    bottom: if y == data.slots.len() { rule-heavy + ink } else { none },
    left: none,
    right: none,
  ),
  inset: (x: 6pt, y: 10pt),

  header-cell("#"),
  header-cell("EXERCISE"),
  header-cell("SETS"),
  header-cell("REPS"),
  header-cell("LOAD"),
  header-cell("UNIT"),
  header-cell("VS LAST"),

  ..data.slots.enumerate().map(((i, slot)) => (
    idx-cell(str(i + 1)),
    name-cell(slot.name),
    num-cell(slot.sets),
    num-cell(slot.reps),
    load-cell(slot.load),
    unit-cell(slot.unit),
    vs-cell(slot.glyph),
  )).flatten()
)

#v(0.5em)
#text(size: 7pt, tracking: 2pt, fill: dim)[
  RIPGROW · #data.profile · #data.date · #str(data.slots.len()) SLOT#if data.slots.len() != 1 [S]
]
