ModsCodeMERGEBLE LLC Search Claude Code Mods

ModsCode / Gallery / Designs / Usage limit bands

Usage limit bands

Two usage limit tracks, the rolling session window and the week, each with an even-pace tick at the time elapsed; use ahead of pace turns Claude orange.

Usage limit bandsUsage limit bands
Usage and limits · 380×140 · sample data
hooks/designs/usage-limits.mjs
// usage-limits: the two Claude usage limits as tracks, in candle's look (8px track at 14% ink, the used
// part at 55%, like gantt's bars). The dashed tick is even pace: the share of the window that has
// passed, so use left of it is on pace or under, and only use past it turns Claude orange, the one accent. The
// sample is 62% of the 5-hour window used at 3h 12m (pace 64%) and 41% of the week used at 3.4 days
// (pace 49%): both sit under pace, so the status reads in UP and no Claude orange shows. Times are written in
// whole hours and minutes (3.4 days is 3d 10h, the week resets in 3d 14h). Sample data only.
const W = 380
const H = 140
const STAGE = '#FAF9F5'
const INK = '#141413'
const MUTED = '#73726C'
const UP = '#2C7A39'
const CLAUDE = '#D77757'
const FONT = "'Inter Tight','Segoe UI',system-ui,sans-serif"
const X0 = 12
const X1 = W - 12
const ROW0 = 24 // the first row's name baseline
const ROW = 56
// used and elapsed are fractions of the window; minutes keep the time text exact
const LIMITS = [
  { name: '5-hour window', used: 0.62, elapsedMin: 192, windowMin: 300 },
  { name: 'Week', used: 0.41, elapsedMin: 3.4 * 24 * 60, windowMin: 7 * 24 * 60 },
]
const f = n => n.toFixed(1)
const text = (x, y, s, { size = 9, fill = MUTED, anchor = 'start' } = {}) =>
  `<text x="${f(x)}" y="${f(y)}"${anchor === 'start' ? '' : ` text-anchor="${anchor}"`} font-size="${size}" font-family="${FONT}" fill="${fill}">${s}</text>`
const bar = (x, y, w, fill, opacity) =>
  `<rect x="${f(x)}" y="${y}" width="${f(w)}" height="8" rx="2" fill="${fill}" fill-opacity="${opacity}"/>`

// 192 -> 3H 12M, 300 -> 5H, 4896 -> 3D 10H, 10080 -> 7D (a day or more drops the minutes)
function span(min) {
  const m = Math.round(min)
  const d = Math.floor(m / 1440)
  if (d) {
    const h = Math.round((m - d * 1440) / 60)
    return h ? `${d}D ${h}H` : `${d}D`
  }
  const h = Math.floor(m / 60)
  return m % 60 ? `${h}H ${m % 60}M` : `${h}H`
}

function track(l, i) {
  const y0 = ROW0 + i * ROW
  const by = y0 + 8 // the track's top
  const x = v => X0 + (X1 - X0) * v
  const pace = l.elapsedMin / l.windowMin
  const ahead = l.used > pace
  const used = Math.round(l.used * 100)
  const diff = Math.round(Math.abs(l.used - pace) * 100)
  const parts = []

  parts.push(text(X0, y0, l.name, { size: 10, fill: INK }))
  parts.push(text(X1, y0, used + '%', { size: 13, fill: INK, anchor: 'end' }))

  parts.push(bar(X0, by, X1 - X0, INK, 0.14))
  // On pace or under, the whole used part is ink; ahead of pace, the part past the tick is Claude orange
  parts.push(bar(X0, by, x(Math.min(l.used, pace)) - X0, INK, 0.55))
  if (ahead) parts.push(bar(x(pace), by, x(l.used) - x(pace), CLAUDE, 0.9))

  // Even pace: a dashed tick 4px past the track, labelled above; the label steps left of the value
  const px = x(pace)
  parts.push(`<line x1="${f(px)}" x2="${f(px)}" y1="${by - 4}" y2="${by + 12}" stroke="${INK}" stroke-opacity="0.35" stroke-dasharray="3 3"/>`)
  const label = `PACE ${Math.round(pace * 100)}%`
  const half = (label.length * 5) / 2
  const valueLeft = X1 - (used + '%').length * 7.5 - 8
  parts.push(px + half < valueLeft ? text(px, y0, label, { anchor: 'middle' }) : text(valueLeft, y0, label, { anchor: 'end' }))

  const ly = by + 24
  const status = ahead ? `${diff}% AHEAD OF PACE` : `${diff}% UNDER PACE`
  parts.push(`<text x="${X0}" y="${ly}" font-size="9" font-family="${FONT}" fill="${MUTED}">${span(l.elapsedMin)} OF ${span(l.windowMin)}<tspan fill="${ahead ? CLAUDE : UP}" dx="8">${status}</tspan></text>`)
  parts.push(text(X1, ly, `RESETS IN ${span(l.windowMin - l.elapsedMin)}`, { anchor: 'end' }))
  return parts.join('')
}

function draw() {
  const parts = [`<rect width="${W}" height="${H}" rx="4" fill="${STAGE}"/>`]
  LIMITS.forEach((l, i) => parts.push(track(l, i)))
  // A hairline between the two rows
  parts.push(`<line x1="${X0}" x2="${X1}" y1="${ROW0 + ROW - 14}" y2="${ROW0 + ROW - 14}" stroke="${INK}" stroke-opacity="0.08"/>`)
  parts.push(text(12, H - 8, 'SAMPLE USAGE LIMITS'))
  return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}">${parts.join('')}</svg>`
}

let source // drawn on first use and kept: the pane loads every design, so none pays at load time
export default {
  id: 'usage-limits',
  title: 'Usage limit bands',
  category: 'usage',
  description: 'Two usage limit tracks, the rolling session window and the week, each with an even-pace tick at the time elapsed; use ahead of pace turns Claude orange.',
  element: ui => ui.Svg({ source: (source ??= draw()), alt: 'Two usage limit tracks for the rolling session window and the week, each with an even-pace tick and reset time, sample data', width: W, height: H }),
}

To use it in a mod: copy the file to your mod's hooks/designs/ and return its element(ui) from a pane's ui.render. How a pane is built.

Code: PolyForm Noncommercial License 1.0.0: noncommercial use only. Required Notice: Copyright 2026 Haruki Nakada (https://modscode.com).