{
  "spec": "quick-html/v0",
  "id": "slide-deck",
  "version": "0.1.0",
  "name": "Slide deck",
  "description": "A 4:3 presentation deck as one self-contained HTML file: cover, agenda, executive summary with stat callouts, repeatable two-column content slides, a financial table, a CSS column chart, a risk table and a closing ask. Arrow-key navigation on screen, one slide per page in print.",
  "useWhen": [
    "slide deck",
    "presentation",
    "board deck",
    "strategy deck",
    "management presentation",
    "steering committee update",
    "investor update deck",
    "html slides",
    "deck i can print to pdf",
    "presentatie",
    "directiepresentatie",
    "präsentation"
  ],
  "format": "deck",
  "theme": "work-projects",
  "audience": [
    "exec",
    "consultant",
    "pmo"
  ],
  "tags": [
    "presentation",
    "slides",
    "board",
    "four-three",
    "print-ready"
  ],
  "language": "en",
  "modules": [
    "deck-runtime",
    "edit-overlay",
    "print-helper"
  ],
  "slots": [
    {
      "name": "doc-title",
      "type": "text",
      "required": true,
      "example": "Strategy review 2026 · Aurora Software B.V.",
      "notes": "Browser tab title; also the filename the Edit module downloads."
    },
    {
      "name": "cover-company",
      "type": "text",
      "required": true,
      "example": "Aurora Software B.V.",
      "notes": "Organisation or project name, top-left on the cover. The deck runtime copies this into the footer of every slide, so it is written once."
    },
    {
      "name": "cover-title",
      "type": "text",
      "required": true,
      "example": "Platform expansion is the only route left to the 2028 plan",
      "notes": "The argument of the whole deck in one line, not a label. Keep under ~70 chars so it stays on two lines."
    },
    {
      "name": "cover-doctype",
      "type": "text",
      "required": true,
      "example": "Strategy review · board session",
      "notes": "What kind of document this is and for whom: 'Quarterly business review', 'Investment proposal', 'Steering committee update'."
    },
    {
      "name": "cover-authors",
      "type": "text",
      "required": true,
      "example": "Prepared by S. Jansen (CFO) and M. de Vries (COO)"
    },
    {
      "name": "cover-date",
      "type": "text",
      "required": true,
      "example": "18 August 2026",
      "notes": "Presentation date, spelled out in the deck's language."
    },
    {
      "name": "agenda-tab",
      "type": "text",
      "required": true,
      "example": "Contents",
      "notes": "Section tab of the agenda slide; translate with the deck ('Inhoud', 'Agenda')."
    },
    {
      "name": "agenda-title",
      "type": "text",
      "required": true,
      "example": "Five questions, thirty minutes, two decisions at the end"
    },
    {
      "name": "summary-tab",
      "type": "text",
      "required": true,
      "example": "Executive summary"
    },
    {
      "name": "summary-title",
      "type": "text",
      "required": true,
      "example": "Seat expansion carried FY26; the 2028 plan needs a second growth engine",
      "notes": "The single most important conclusion in the deck."
    },
    {
      "name": "summary-body",
      "type": "html",
      "required": true,
      "example": "<ul class=\"b\"><li>Revenue grew 14,7% to € 4,9 million, but 94% came from existing customers.</li><li>Seat capacity runs out in FY28 on current penetration.<ul><li>Top 20 accounts sit at 71% penetration.</li></ul></li></ul>",
      "notes": "Keep the <ul class=\"b\"> wrapper. Two to four level-1 bullets, each a full conclusion with its number; nest at most one <ul> for evidence."
    },
    {
      "name": "summary-takeaway",
      "type": "text",
      "required": true,
      "example": "Without a second engine the FY28 revenue line is € 1,8 million short; the platform module closes it if we start hiring in Q1 FY27.",
      "notes": "The so-what strip. One sentence, states the consequence, not a summary of the bullets."
    },
    {
      "name": "table-tab",
      "type": "text",
      "required": true,
      "example": "Business case",
      "notes": "Lives on the optional table slide."
    },
    {
      "name": "table-title",
      "type": "text",
      "required": true,
      "example": "Every euro of FY27 growth above inflation comes from the new platform line"
    },
    {
      "name": "table-head-label",
      "type": "text",
      "required": true,
      "example": "€ thousand",
      "notes": "First column header: put the unit here, never in the cells."
    },
    {
      "name": "table-head-a",
      "type": "text",
      "required": true,
      "example": "FY24"
    },
    {
      "name": "table-head-b",
      "type": "text",
      "required": true,
      "example": "FY25"
    },
    {
      "name": "table-head-c",
      "type": "text",
      "required": true,
      "example": "FY26 F"
    },
    {
      "name": "table-head-d",
      "type": "text",
      "required": true,
      "example": "FY27 P",
      "notes": "Four value columns is the layout; if you need fewer, repeat the last period or reuse the column for a variance."
    },
    {
      "name": "table-total-label",
      "type": "text",
      "required": true,
      "example": "Net revenue",
      "notes": "The ruled totals row. It must equal the sum of the rows above it."
    },
    {
      "name": "table-total-a",
      "type": "text",
      "required": true,
      "example": "3.770"
    },
    {
      "name": "table-total-b",
      "type": "text",
      "required": true,
      "example": "4.261"
    },
    {
      "name": "table-total-c",
      "type": "text",
      "required": true,
      "example": "4.887"
    },
    {
      "name": "table-total-d",
      "type": "text",
      "required": true,
      "example": "5.694"
    },
    {
      "name": "table-takeaway",
      "type": "text",
      "required": true,
      "example": "Revenue grows 16,5% in FY27; strip out the € 430k platform line nobody has bought yet and growth is 7,7%.",
      "notes": "The so-what of the table: name the one number that carries the argument and what it depends on."
    },
    {
      "name": "table-source",
      "type": "text",
      "required": false,
      "example": "Source: FY24 and FY25 audited; FY26 forecast per the July re-forecast; FY27 per the operating plan v2.1.",
      "notes": "Say which figures are actual, forecast or plan. Clear the text if there is nothing to cite."
    },
    {
      "name": "chart-tab",
      "type": "text",
      "required": true,
      "example": "Where growth came from",
      "notes": "Lives on the optional chart slide."
    },
    {
      "name": "chart-title",
      "type": "text",
      "required": true,
      "example": "New-logo revenue has been flat for three years while expansion tripled",
      "notes": "State what the chart proves, not what it plots."
    },
    {
      "name": "series-a-name",
      "type": "text",
      "required": true,
      "example": "Existing customers",
      "notes": "Accent-coloured series."
    },
    {
      "name": "series-b-name",
      "type": "text",
      "required": true,
      "example": "New logos",
      "notes": "Warm-grey secondary series."
    },
    {
      "name": "chart-scale-note",
      "type": "text",
      "required": true,
      "example": "€ million, net revenue after churn; FY26 forecast.",
      "notes": "Unit and basis of the bars. The chart has no y-axis, so this line carries the scale."
    },
    {
      "name": "chart-takeaway",
      "type": "text",
      "required": true,
      "example": "Expansion revenue doubled in three years; new-logo revenue has not moved since FY24."
    },
    {
      "name": "chart-source",
      "type": "text",
      "required": false,
      "example": "Source: finance mart cohort analysis, 4 August 2026.",
      "notes": "Clear the text if there is nothing to cite."
    },
    {
      "name": "risk-tab",
      "type": "text",
      "required": true,
      "example": "Risks",
      "notes": "Lives on the optional risk slide."
    },
    {
      "name": "risk-title",
      "type": "text",
      "required": true,
      "example": "Delivery capacity is the only risk that can break the case on its own"
    },
    {
      "name": "risk-head-item",
      "type": "text",
      "required": true,
      "example": "Risk",
      "notes": "The four headers make this table reusable: Risk/Rating/Why it matters/What we do, or Issue/Owner/Impact/Action."
    },
    {
      "name": "risk-head-rating",
      "type": "text",
      "required": true,
      "example": "Rating"
    },
    {
      "name": "risk-head-comment",
      "type": "text",
      "required": true,
      "example": "Why it matters"
    },
    {
      "name": "risk-head-mitigation",
      "type": "text",
      "required": true,
      "example": "What we do about it"
    },
    {
      "name": "next-tab",
      "type": "text",
      "required": true,
      "example": "Next steps"
    },
    {
      "name": "next-title",
      "type": "text",
      "required": true,
      "example": "Four steps in the next 60 days, two of which need a decision today"
    },
    {
      "name": "next-head-step",
      "type": "text",
      "required": true,
      "example": "Step"
    },
    {
      "name": "next-head-owner",
      "type": "text",
      "required": true,
      "example": "Owner"
    },
    {
      "name": "next-head-when",
      "type": "text",
      "required": true,
      "example": "By"
    },
    {
      "name": "next-ask",
      "type": "text",
      "required": true,
      "example": "We ask the board to approve € 2,4 million of platform investment across FY27 and FY28, and the two senior engineering hires in step 1.",
      "notes": "The ask, in the accent strip: name the decision, the amount and the deadline. If the deck asks for nothing, say what happens next instead."
    }
  ],
  "repeats": [
    {
      "name": "agenda-item",
      "description": "One numbered line on the agenda slide. Keep the wording identical to the section tab of the slides it covers.",
      "min": 3,
      "max": 8,
      "slots": [
        {
          "name": "agenda-item-text",
          "type": "text",
          "required": true,
          "example": "Where we stand: FY26 year to date",
          "notes": "One line, under ~60 chars, no trailing full stop."
        }
      ]
    },
    {
      "name": "stat",
      "description": "One headline number on the executive summary slide.",
      "min": 2,
      "max": 4,
      "slots": [
        {
          "name": "stat-value",
          "type": "text",
          "required": true,
          "example": "€ 412k",
          "notes": "The figure with its unit, short enough to stay on one line."
        },
        {
          "name": "stat-label",
          "type": "text",
          "required": true,
          "example": "Monthly recurring revenue, July 2026",
          "notes": "What it measures and as of when; under ~45 chars."
        }
      ]
    },
    {
      "name": "content-slide",
      "description": "The workhorse slide: section tab, so-what title, two ruled columns, a takeaway strip and a source line. Duplicate it once per argument in the deck; the order of the copies is the order of the deck.",
      "min": 1,
      "max": 14,
      "slots": [
        {
          "name": "slide-tab",
          "type": "text",
          "required": true,
          "example": "Where we stand",
          "notes": "The chapter this slide belongs to. Repeat the same tab on consecutive slides of one chapter, and keep the wording equal to the matching agenda line."
        },
        {
          "name": "slide-title",
          "type": "text",
          "required": true,
          "example": "Growth was real but narrow: one motion worked, the other stalled",
          "notes": "A conclusion, not a label. Under ~80 chars so it stays within two lines."
        },
        {
          "name": "col-a-head",
          "type": "text",
          "required": true,
          "example": "What worked",
          "notes": "Short uppercase sub-header, under ~28 chars."
        },
        {
          "name": "col-a-body",
          "type": "html",
          "required": true,
          "example": "<ul class=\"b\"><li>Seat expansion added € 0,59 million, 94% of total growth.</li><li>Net revenue retention held above 105% every quarter.</li></ul>",
          "notes": "Keep the <ul class=\"b\"> wrapper. Two to four bullets of at most ~22 words; one nested <ul> allowed for evidence."
        },
        {
          "name": "col-b-head",
          "type": "text",
          "required": true,
          "example": "What did not"
        },
        {
          "name": "col-b-body",
          "type": "html",
          "required": true,
          "example": "<ul class=\"b\"><li>New logos came in at 23 against a plan of 26.</li><li>Pipeline coverage sits at 2,1x against the 3,0x we need.</li></ul>",
          "notes": "Same rules as col-a-body. Balance the two columns: a half-empty right column reads as an unfinished slide."
        },
        {
          "name": "slide-takeaway",
          "type": "text",
          "required": true,
          "example": "The engine that grew FY26 is the engine that runs out in FY28: expansion cannot be the plan twice.",
          "notes": "One sentence that lands the consequence of this slide."
        },
        {
          "name": "slide-source",
          "type": "text",
          "required": false,
          "example": "Source: finance mart, dbt snapshot of 4 August 2026; CRM pipeline export, week 31.",
          "notes": "Required on any slide with data. Clear the text on slides that carry only judgement."
        }
      ]
    },
    {
      "name": "table-row",
      "description": "One line of the financial table, above the ruled totals row.",
      "min": 2,
      "max": 10,
      "slots": [
        {
          "name": "row-label",
          "type": "text",
          "required": true,
          "example": "Subscription",
          "notes": "Under ~30 chars; no unit (the unit lives in the first column header)."
        },
        {
          "name": "row-a",
          "type": "text",
          "required": true,
          "example": "2.980",
          "notes": "Number only, same decimals down the column. Negatives in parentheses."
        },
        {
          "name": "row-b",
          "type": "text",
          "required": true,
          "example": "3.410"
        },
        {
          "name": "row-c",
          "type": "text",
          "required": true,
          "example": "3.985"
        },
        {
          "name": "row-d",
          "type": "text",
          "required": true,
          "example": "4.320"
        }
      ]
    },
    {
      "name": "bar-group",
      "description": "One period on the column chart: an accent bar and a grey bar side by side.",
      "min": 2,
      "max": 8,
      "slots": [
        {
          "name": "bar-label",
          "type": "text",
          "required": true,
          "example": "FY23",
          "notes": "Category label under the pair, under ~10 chars."
        },
        {
          "name": "bar-a-value",
          "type": "text",
          "required": true,
          "example": "1,9",
          "notes": "Printed above the accent bar, in the unit named in chart-scale-note."
        },
        {
          "name": "bar-a-style",
          "type": "text",
          "required": true,
          "example": "height:44%",
          "notes": "EXACTLY 'height:NN%'. NN = value divided by the single largest value across BOTH series, times 100, rounded, maximum 92 so the tallest bar leaves room for its label. No spaces."
        },
        {
          "name": "bar-b-value",
          "type": "text",
          "required": true,
          "example": "0,8",
          "notes": "Printed above the grey bar."
        },
        {
          "name": "bar-b-style",
          "type": "text",
          "required": true,
          "example": "height:18%",
          "notes": "Same formula and the same divisor as bar-a-style: both series share one scale, or the chart lies."
        }
      ]
    },
    {
      "name": "risk-row",
      "description": "One row of the risk table.",
      "min": 2,
      "max": 8,
      "slots": [
        {
          "name": "risk-item",
          "type": "text",
          "required": true,
          "example": "Platform delivery slips",
          "notes": "Name the risk in under ~30 chars."
        },
        {
          "name": "risk-rating",
          "type": "text",
          "required": true,
          "example": "High",
          "notes": "The chip text: High / Medium / Low, translated with the deck. Must agree with risk-rating-class."
        },
        {
          "name": "risk-rating-class",
          "type": "text",
          "required": true,
          "example": "chip chip-bad",
          "notes": "EXACTLY one of 'chip chip-bad' (high), 'chip chip-warn' (medium), 'chip chip-good' (low)."
        },
        {
          "name": "risk-comment",
          "type": "text",
          "required": true,
          "example": "Two engineers carry both the core roadmap and the module; a single departure moves the launch by a quarter.",
          "notes": "The mechanism: how the risk actually hurts, with a number where possible."
        },
        {
          "name": "risk-mitigation",
          "type": "text",
          "required": true,
          "example": "Ring-fence the module team from support rotation and start both hires before the board decision lands.",
          "notes": "A concrete action with an owner or a date, not a reassurance."
        }
      ]
    },
    {
      "name": "next-step",
      "description": "One row of the next-steps table.",
      "min": 2,
      "max": 8,
      "slots": [
        {
          "name": "step-text",
          "type": "text",
          "required": true,
          "example": "Open both Berlin engineering requisitions and brief the search partner.",
          "notes": "Start with a verb; one action per row."
        },
        {
          "name": "step-owner",
          "type": "text",
          "required": true,
          "example": "M. de Vries",
          "notes": "A person or a named team, never 'TBD'."
        },
        {
          "name": "step-when",
          "type": "text",
          "required": true,
          "example": "1 Sep 2026",
          "notes": "A date, not 'Q4'."
        }
      ]
    }
  ],
  "optionals": [
    {
      "name": "table-slide",
      "description": "Financial or business-case table slide with a ruled totals row. Remove it when the deck carries no figures."
    },
    {
      "name": "chart-slide",
      "description": "Two-series column chart slide. Remove it when there is no trend worth plotting; one honest chart beats three decorative ones."
    },
    {
      "name": "risk-slide",
      "description": "Risk / issue table with rating chips. Remove it for a purely informational deck."
    }
  ],
  "changelog": [
    {
      "version": "0.1.0",
      "date": "2026-08-18",
      "notes": "Initial release: 4:3 deck with cover, agenda, executive summary with stat callouts, repeatable two-column content slide, financial table, CSS column chart, risk table and closing ask. Print target 254 x 190,5 mm, one slide per page."
    }
  ],
  "agentInstructions": "SHAPE THE DECK FIRST, THEN FILL IT. 1) Duplicate the content-slide block once per argument you need: the copies stay in place and their order is the deck order. Group them into chapters by repeating the same slide-tab on consecutive slides. 2) Remove the optional slides you do not need (table-slide, chart-slide, risk-slide) and delete every data-example element: the shipped extra agenda lines, stat tiles, table rows, bar groups, risk rows, step rows and the second example content slide. 3) Make the agenda lines match the section tabs of the slides they cover, in the same order. TITLES CARRY THE ARGUMENT: every title is a full conclusion ('New-logo revenue has been flat for three years'), never a label ('Revenue overview'); if a title does not survive being read on its own, rewrite it. Fill the takeaway strip on every slide that has one, with the consequence rather than a restatement. DO NOT NUMBER SLIDES OR REPEAT THE COMPANY NAME PER SLIDE: the deck-runtime module fills every page number, the slide total and the footer brand from cover-company at load time, so inserting or reordering slides can never leave a stale number. COMPUTE EVERY NUMBER YOURSELF AND RE-CHECK IT: the totals row must equal the sum of its rows; bar heights are 'height:NN%' with NN = value divided by the largest value across BOTH series, times 100, rounded, capped at 92, and both series must use that same divisor; risk-rating-class is EXACTLY 'chip chip-bad' | 'chip chip-warn' | 'chip chip-good' and must agree with the chip text. DENSITY: two to four bullets per column of at most ~22 words, both columns filled; a half-empty slide reads as unfinished. Mirror the placeholder number format (decimal comma, thousands point, '€ 412k'), and for a Dutch or German deck translate the tabs, headers, chart labels and the agenda too. Leave [PLACEHOLDER] where a figure is genuinely unknown and tell the user to fill it with the built-in Edit button. THE DECK IS 4:3 AND PRINTS ONE SLIDE PER PAGE at 254 x 190,5 mm: do not change the slide size, the em-based sizing or the @page rule, and keep -webkit-print-color-adjust / print-color-adjust in place or the accent bars and table headers drop out of the PDF.",
  "license": "MIT",
  "authors": [
    {
      "github": "bvrln"
    }
  ]
}
