Dossierby Mathieu Mahoudeau

Features · Blocks

Twenty-three blocks. No blank canvas.

A slide is a title and a few typed blocks. Your agent picks from these and fills them in; the server refuses anything else, so a deck can't come out broken. Every one below is the real block, rendered by Dossier, telling one made-up company's quarter.

Text

Words, set to read from the back of the room.

Text

A paragraph.

JSON
{
  "type": "text",
  "props": {
    "text": "Nine ports now run on one schedule, and the delays went with it.",
    "size": "tagline"
  }
}

Section label

A small heading inside a slide.

JSON
{
  "type": "heading",
  "props": {
    "text": "What changed this quarter",
    "style": "bar"
  }
}

Bullets

An unordered list with gradient dots.

JSON
{
  "type": "bullets",
  "props": {
    "items": [
      "**One plan**, read by all nine ports.",
      "Delays flagged before the ship leaves.",
      "Crews see changes on their phones."
    ]
  }
}

Numbered steps

An ordered list for a procedure.

JSON
{
  "type": "steps",
  "props": {
    "items": [
      "Import each port's calendar.",
      "Merge the berths into one plan.",
      "Publish it to every harbour master."
    ]
  }
}

Quote

A pull quote with a gradient rule.

JSON
{
  "type": "quote",
  "props": {
    "text": "For the first time, Rotterdam and Gdańsk argue over the same plan.",
    "cite": "Head of operations, Harbour Co."
  }
}

Turn

The pivot line of a slide.

JSON
{
  "type": "turn",
  "props": {
    "text": "The fix was never more ships. It was **one schedule everyone reads**."
  }
}

Questions to the room

Large numbered questions.

JSON
{
  "type": "asks",
  "props": {
    "items": [
      "Which port should pilot berth swaps first?",
      "What would make you trust a swap agreed without a call?"
    ]
  }
}

Markdown

Free Markdown for one-offs (headings, lists, tables, links).

JSON
{
  "type": "markdown",
  "props": {
    "md": "## Ports on the plan\n\n- **Rotterdam**, since March\n- **Antwerp**, since May\n- **Gdańsk**, since August\n\nMore in [the full review](https://www.getdossier.dev)."
  }
}

Numbers

The figure first, the story under it.

Stats

Big numbers as the hero.

JSON
{
  "type": "stats",
  "props": {
    "items": [
      {
        "value": "38",
        "unit": "%",
        "label": "fewer missed berths",
        "hero": true
      },
      {
        "value": "9",
        "label": "ports on one schedule"
      },
      {
        "value": "4.2",
        "unit": "h",
        "label": "saved per vessel call"
      }
    ]
  }
}

Bars

Horizontal bars to true scale.

JSON
{
  "type": "bars",
  "props": {
    "items": [
      {
        "label": "Shared schedule",
        "value": 62,
        "display": "62 min"
      },
      {
        "label": "Local spreadsheets",
        "value": 240,
        "display": "4 h",
        "tone": "muted"
      }
    ]
  }
}

Disproportion

Two or three numbers with rails drawn to true scale, so the gap is seen rather than parsed.

JSON
{
  "type": "dispro",
  "props": {
    "items": [
      {
        "value": "1",
        "ratio": 0.11,
        "label": "schedule now"
      },
      {
        "value": "9",
        "ratio": 1,
        "label": "schedules before"
      }
    ]
  }
}

Table

A data table.

JSON
{
  "type": "table",
  "props": {
    "columns": [
      {
        "label": "Port"
      },
      {
        "label": "Missed berths, Q3",
        "numeric": true
      },
      {
        "label": "Q4",
        "numeric": true
      }
    ],
    "rows": [
      [
        "Rotterdam",
        "14",
        "**6**"
      ],
      [
        "Antwerp",
        "11",
        "**5**"
      ],
      [
        "Gdańsk",
        "9",
        "**4**"
      ]
    ]
  }
}

Kill criteria

Failure conditions as columns: a claim, then its verdict values at the bottom.

JSON
{
  "type": "kills",
  "props": {
    "items": [
      {
        "claim": "Missed berths climb back",
        "values": [
          {
            "value": ">10",
            "label": "a month",
            "hero": true
          },
          {
            "value": "2 mo",
            "label": "in a row"
          }
        ]
      },
      {
        "claim": "Ports stop reading the plan",
        "values": [
          {
            "value": "<70%",
            "label": "daily opens",
            "hero": true
          },
          {
            "value": "4 wk",
            "label": "window"
          }
        ]
      }
    ]
  }
}

Structure

Choices, sequences and trade-offs, side by side.

Panels

A row of cards.

JSON
{
  "type": "panels",
  "props": {
    "columns": "3",
    "items": [
      {
        "label": "Kept",
        "title": "One shared schedule",
        "body": "Every port reads the same plan.",
        "tone": "primary",
        "fill": true
      },
      {
        "label": "Cut",
        "title": "Local spreadsheets",
        "body": "Nine versions of the truth.",
        "tone": "secondary"
      },
      {
        "label": "Next",
        "title": "Live berth swaps",
        "body": "Ports trade slots on their own.",
        "tone": "tertiary"
      }
    ]
  }
}

Ladder

Ordered rungs, each with a short mono label and a line of text.

JSON
{
  "type": "ladder",
  "props": {
    "items": [
      {
        "label": "Q1",
        "text": "Two pilot ports on the shared plan."
      },
      {
        "label": "Q2",
        "text": "Five ports, berth swaps by phone."
      },
      {
        "label": "Q3",
        "text": "Nine ports, delays flagged a day ahead."
      },
      {
        "label": "Q4",
        "text": "Swaps agreed without a call."
      }
    ]
  }
}

Flow

A process as a row of stages with arrows, each stage one stop along the gradient.

JSON
{
  "type": "flow",
  "props": {
    "steps": [
      "Plan",
      "Publish",
      "Dock",
      "Review"
    ]
  }
}

Q and A

Question and answer pairs in two columns.

JSON
{
  "type": "qa",
  "props": {
    "items": [
      {
        "q": "Why not a new system per port?",
        "a": "Nine systems is how we got nine schedules."
      },
      {
        "q": "What if a port goes offline?",
        "a": "It keeps the last plan and syncs when it's back."
      }
    ]
  }
}

Pills

Small status pills.

JSON
{
  "type": "pills",
  "props": {
    "items": [
      {
        "label": "Live in 9 ports",
        "tone": "success"
      },
      {
        "label": "Swaps in pilot",
        "tone": "warning"
      },
      {
        "label": "Billing next",
        "tone": "info"
      }
    ]
  }
}

Around the blocks

Covers, content, sections and an appendix that numbers itself. A kicker, a title, a tagline. One gradient moment a slide. Notes for rehearsal that never leave the editor.

Checked before anyone sees it

Every slide is rendered in a real browser before it's saved: overflow, broken images, hard-to-read text and dead links come back with the slide and the block.

Private beta

Let your agent write the next one.

Join the waitlist