{# ── Theme CSS variables ──────────────────────────────────────────────────── #} {% if theme %} {% set _sc = "dark" if dark_mode else "light" %} {% set p = theme["schemes." ~ _sc ~ ".primary"] %} {% set s = theme["schemes." ~ _sc ~ ".secondary"] %} {% set bg = theme["schemes." ~ _sc ~ ".background"] %} {% set txt = theme["schemes." ~ _sc ~ ".onBackground"] %} {% set err = theme.get("schemes." ~ _sc ~ ".error", "#d32f2f") %} {% set ter = theme.get("schemes." ~ _sc ~ ".tertiary", "#008032") %} {% endif %} {# ── html_attrs: emit arbitrary HTML attrs from a dict ───────────────────────── #} {# Empty-string values emit bare attribute (e.g. disabled); others emit key="val" #} {% macro html_attrs(attrs) %}{% if attrs %}{% for k, v in attrs.items() %} {% if v == '' %}{{ k }}{% else %}{{ k }}="{{ v | e }}"{% endif %}{% endfor %}{% endif %}{% endmacro %} {# ── group_child: render a child of mt.input_group() (children/.prefix/.suffix) ─ #} {# oat.ink's fieldset.group > :is(input,textarea,select){flex:1} only matches DIRECT children, and .group is display:flex so a {% else %} {{ render_component(child) }} {% endif %} {% endmacro %} {# ── render_children: render a list of components, handling tab/column grouping ─ #} {% macro render_children(children) %} {% for comp in children %} {% if comp.type == 'column' %} {% if loop.index0 == 0 or children[loop.index0 - 1].type != 'column' %}
{% endif %}
{{ render_children(comp.children) }}
{% if loop.last or children[loop.index0 + 1].type != 'column' %}
{% endif %} {% elif comp.type == 'tab' %} {% if loop.index0 == 0 or children[loop.index0 - 1].type != 'tab' %} {% set tab_start = loop.index0 %} {% set tab_id_ns = namespace(value='', done=false) %} {% for fc in children[tab_start:] %} {% if fc.type == 'tab' and not tab_id_ns.done %} {% set tab_id_ns.value = tab_id_ns.value ~ '-' ~ fc.label | replace(' ', '-') %} {% else %} {% set tab_id_ns.done = true %} {% endif %} {% endfor %}
{% set hdr_ns = namespace(stop=false) %} {% for fc in children[tab_start:] %} {% if not hdr_ns.stop %} {% if fc.type == 'tab' %} {% else %} {% set hdr_ns.stop = true %} {% endif %} {% endif %} {% endfor %}
{% endif %}
{{ render_children(comp.children) }}
{% if loop.last or children[loop.index0 + 1].type != 'tab' %}
{% endif %} {% else %} {{ render_component(comp) }} {% endif %} {% endfor %} {% endmacro %} {% macro render_component(comp) %} {# grid_col must stay display:contents too — .row is display:flex and needs the real .col-N div as its direct flex child, or flex:0 0 N% never applies and the column (and everything inside it) shrinks to fit its content instead. #} {% set _tbl_inline = ['html_table','table_head','table_body','table_foot','table_row','table_cell','grid_col'] %}
{# ── Typography ──────────────────────────────────────────────────────── #} {% if comp.type == 'title' %}

{{ comp.content }}

{% elif comp.type == 'header' %}

{{ comp.content }}

{% elif comp.type == 'subheader' %}

{{ comp.content }}

{% elif comp.type == 'write' or comp.type == 'text' %}

{{ comp.content }}

{% elif comp.type == 'markdown' %}
{{ comp.content | safe }}
{% elif comp.type == 'code' %}
{{ comp.content }}
{% elif comp.type == 'html' %}
{{ comp.content | safe }}
{% elif comp.type == 'latex' %}
$${{ comp.content }}$$
{% elif comp.type == 'json' %}
{{ comp.content }}
{# ── NER highlighting ────────────────────────────────────────────────── #} {% elif comp.type == 'ner' %}
{% set text_content = comp.content %} {% set ns_ner = namespace(last_idx=0) %} {% for ent in comp.entities %} {{ text_content[ns_ner.last_idx:ent.start] }} {{ text_content[ent.start:ent.end] }} {{ ent.label }} {% set ns_ner.last_idx = ent.end %} {% endfor %} {{ text_content[ns_ner.last_idx:] }}
{# ── Streaming text ──────────────────────────────────────────────────── #} {% elif comp.type == 'write_stream' %}
{# ── Data / Table ────────────────────────────────────────────────────── #} {% elif comp.type == 'dataframe' or comp.type == 'table' %}
{{ comp.content | safe }}
{# ── Metric card ─────────────────────────────────────────────────────── #} {% elif comp.type == 'metric' %}
{{ comp.label }} {{ comp.value }} {% if comp.delta %} {% set delta_class = 'positive' if not comp.delta.startswith('-') else 'negative' %} {{ comp.delta }} {% endif %}
{# ── Badge ───────────────────────────────────────────────────────────── #} {% elif comp.type == 'badge' %} {{ comp.content }} {# ── Status / Alert ──────────────────────────────────────────────────── #} {% elif comp.type == 'status' %}
{{ comp.content }}
{# ── Widgets ─────────────────────────────────────────────────────────── #} {% elif comp.type == 'button' %} {# OAT's default button (no data-variant) is the primary filled style — only emit the attribute when a variant was actually requested, or every button always rendered as OAT's "secondary" look. #} {% elif comp.type == 'text_input' %} {% elif comp.type == 'email_input' %} {% elif comp.type == 'password_input' %} {% elif comp.type == 'datetime_input' %} {% elif comp.type == 'text_area' %} {% elif comp.type == 'number_input' %} {% elif comp.type == 'date_input' %} {% elif comp.type == 'color_picker' %} {% elif comp.type == 'checkbox' %} {% elif comp.type == 'toggle' %} {% elif comp.type == 'slider' %} {% elif comp.type == 'radio' %}
{{ comp.label }} {% for option in comp.options %} {% endfor %}
{% elif comp.type == 'selectbox' %}
{# ── Media ───────────────────────────────────────────────────────────── #} {% elif comp.type == 'image' %}
{{ comp.caption | default('') }}
{% elif comp.type == 'logo' %}
Logo
{% elif comp.type == 'audio' %}
{% elif comp.type == 'video' %}
{# ── Charts ──────────────────────────────────────────────────────────── #} {% elif comp.type in ('line_chart', 'bar_chart', 'area_chart', 'scatter_chart', 'chart') %}
{# ── Layout: container ───────────────────────────────────────────────── #} {% elif comp.type == 'container' %}
{{ render_children(comp.children) }}
{# ── Layout: expander ────────────────────────────────────────────────── #} {% elif comp.type == 'expander' %}
{% if comp.icon %}{{ comp.icon }} {% endif %}{{ comp.label }}
{{ render_children(comp.children) }}
{# ── Layout: card (CompositeComponent) ───────────────────────────────── #} {% elif comp.type == 'card' %}
{% if comp.slot_header is defined and comp.slot_header %}
{% for child in comp.slot_header %}{{ render_component(child) }}{% endfor %}
{% elif comp.header %}

{{ comp.header }}

{% endif %} {% for child in comp.children %} {{ render_component(child) }} {% endfor %} {% if comp.slot_footer is defined and comp.slot_footer %}
{% for child in comp.slot_footer %}{{ render_component(child) }}{% endfor %}
{% elif comp.footer %}
{{ comp.footer }}
{% endif %}
{# ── OAT UI primitives ───────────────────────────────────────────────── #} {% elif comp.type == 'spinner' %}
{% elif comp.type == 'progress' %} {% if comp.value is not none %} {% else %} {% endif %} {% elif comp.type == 'skeleton' %}
{% elif comp.type == 'meter' %} {# ── Avatar ──────────────────────────────────────────────────────────── #} {% elif comp.type == 'avatar' %} {# aria-label on the
already carries the accessible name — img alt stays empty/decorative, or a screen reader announces the name twice. #}
{% if comp.src %} {% else %} {{ comp.initials | default('') }} {% endif %}
{% elif comp.type == 'avatar_group' %}
{% for av in comp.avatars %}
{% if av.src %} {% else %} {{ av.initials | default('') }} {% endif %}
{% endfor %}
{# ── Breadcrumb ──────────────────────────────────────────────────────── #} {% elif comp.type == 'breadcrumb' %} {# ── Button Group ────────────────────────────────────────────────────── #} {% elif comp.type == 'button_group' %} {% for btn in comp.buttons %}
  • {% endfor %}
    {# ── Toast ───────────────────────────────────────────────────────────── #} {# oat.ink API: ot.toast(message, title?, options?) #} {% elif comp.type == 'toast' %} {# ── Pagination ──────────────────────────────────────────────────────── #} {% elif comp.type == 'pagination' %} {# ── Dialog ──────────────────────────────────────────────────────────── #} {% elif comp.type == 'dialog' %} {% set _dlg_id = "dlg-" ~ comp.id %}
    {% if comp.slot_header is defined and comp.slot_header %}
    {% for child in comp.slot_header %}{{ render_component(child) }}{% endfor %}
    {% elif comp.title %}

    {{ comp.title }}

    {% endif %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {% if comp.slot_footer is defined and comp.slot_footer %}
    {% for child in comp.slot_footer %}{{ render_component(child) }}{% endfor %}
    {% else %}
    {% endif %}
    {# ── Dropdown ────────────────────────────────────────────────────────── #} {# oat.ink uses popovertarget/popover — NOT slot="trigger" #} {% elif comp.type == 'dropdown' %} {% set _menu_id = "menu-" ~ comp.id %} {% for item in comp['items'] %} {% if item.href is defined and item.href %} {{ item.label }} {% else %} {% endif %} {% endfor %} {# ── Grid ────────────────────────────────────────────────────────────── #} {# oat.ink's .container carries page-root padding/max-width/centering — mxlit's
    already owns that job, so neutralize them here or a nested grid ends up double-inset from the page edge. #} {% elif comp.type == 'grid' %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {# ── Grid Row ─────────────────────────────────────────────────────────── #} {# oat.ink's own .row is display:grid + gap — use it natively instead of a hand-rolled flex-basis %, which ignored .row's gap and overflowed/wrapped. #} {% elif comp.type == 'grid_row' %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {# ── Grid Col ─────────────────────────────────────────────────────────── #} {# oat.ink's [class*=col-] reads --span/--offset custom props to size the grid-column span — set them directly so any span/offset value works, not just the offset-1..offset-6 classes oat.min.css predefines. #} {% elif comp.type == 'grid_col' %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {# ── HTML Table ───────────────────────────────────────────────────────── #} {% elif comp.type == 'html_table' %} {% if comp.caption %}{% endif %} {% for child in comp.children %}{{ render_component(child) }}{% endfor %}
    {{ comp.caption | e }}
    {# ── Table Head ───────────────────────────────────────────────────────── #} {% elif comp.type == 'table_head' %} {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {# ── Table Body ───────────────────────────────────────────────────────── #} {% elif comp.type == 'table_body' %} {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {# ── Table Foot ───────────────────────────────────────────────────────── #} {% elif comp.type == 'table_foot' %} {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {# ── Table Row ────────────────────────────────────────────────────────── #} {% elif comp.type == 'table_row' %} {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {# ── Table Cell ───────────────────────────────────────────────────────── #} {% elif comp.type == 'table_cell' %} {% if comp.header %} 1 %}colspan="{{ comp.colspan }}"{% endif %} {% if comp.rowspan > 1 %}rowspan="{{ comp.rowspan }}"{% endif %} {% if comp.scope %}scope="{{ comp.scope }}"{% endif %} {{ html_attrs(comp.attrs) | safe }}> {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {% else %} 1 %}colspan="{{ comp.colspan }}"{% endif %} {% if comp.rowspan > 1 %}rowspan="{{ comp.rowspan }}"{% endif %} {{ html_attrs(comp.attrs) | safe }}> {% for child in comp.children %}{{ render_component(child) }}{% endfor %} {% endif %} {# ── File Input ──────────────────────────────────────────────────────── #} {% elif comp.type == 'file_input' %} {# ── Input Group ─────────────────────────────────────────────────────── #} {# oat.ink:
    prefix {% for option in comp.options %} {% endfor %}
    {# ── Select Slider ───────────────────────────────────────────────────── #} {% elif comp.type == 'select_slider' %} {# ── Time Input ──────────────────────────────────────────────────────── #} {% elif comp.type == 'time_input' %} {# ── Link Button ─────────────────────────────────────────────────────── #} {% elif comp.type == 'link_button' %} {{ comp.label }} {# ── Download Button ─────────────────────────────────────────────────── #} {% elif comp.type == 'download_button' %} {{ comp.label }} {# ── Pills ───────────────────────────────────────────────────────────── #} {# Single-select pill buttons — styled like radio but rendered as chips #} {% elif comp.type == 'pills' %}
    {{ comp.label }} {% for option in comp.options %}
  • {% endfor %}
    {# ── Feedback ────────────────────────────────────────────────────────── #} {% elif comp.type == 'feedback' %}
    {% if comp.label %}{{ comp.label }}{% endif %} {% if comp.sentiment == 'thumbs' %}
  • {% else %} {% for star in [1, 2, 3, 4, 5] %}
  • {% endfor %} {% endif %}
    {# ── Space ───────────────────────────────────────────────────────────── #} {% elif comp.type == 'space' %} {# ── Empty placeholder ───────────────────────────────────────────────── #} {% elif comp.type == 'empty' %} {# ── Popover ─────────────────────────────────────────────────────────── #} {% elif comp.type == 'popover' %} {% set _pop_id = "pop-" ~ comp.id %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {# ── Status container ────────────────────────────────────────────────── #} {% elif comp.type == 'status_box' %} {% set _state_icon = {'running': '', 'complete': '✓', 'error': '✗'} %}
    {% if comp.state == 'running' %} {% elif comp.state == 'complete' %} {% else %} {% endif %} {{ comp.label }}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {# column / tab / sidebar are handled by the outer loop #} {% elif comp.type == 'column' %}{% elif comp.type == 'tab' %}{% elif comp.type == 'sidebar' %} {% else %}
    Unsupported component type: {{ comp.type }}
    {% endif %} {% endmacro %} {# ── Navbar ────────────────────────────────────────────────────────────────── #} {% set ns_nav = namespace(has_navbar=false) %} {% for comp in components %} {% if comp.type == 'navbar' %}{% set ns_nav.has_navbar = true %}{% endif %} {% endfor %} {% if ns_nav.has_navbar %} {% for comp in components %} {% if comp.type == 'navbar' %}
    {% for child in comp.children %} {{ render_component(child) }} {% endfor %}
    {% endif %} {% endfor %} {% endif %} {# ── Sidebar ──────────────────────────────────────────────────────────────── #} {% set ns = namespace(has_sidebar=false) %} {% for comp in components %} {% if comp.type == 'sidebar' %}{% set ns.has_sidebar = true %}{% endif %} {% endfor %} {% if ns.has_sidebar %} {% for comp in components %} {% if comp.type == 'sidebar' %} {# oat.ink's aside[data-sidebar] is display:flex;flex-direction:column with >:is(header,footer){flex-shrink:0} — header/footer must be direct children of