array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/account-navigation', 'version' => '1.0.0', 'title' => 'Account navigation', 'category' => 'theme', 'icon' => 'admin-users', 'description' => 'The account areas\' navigation beside the content (the application shell, contract C3@2): WooCommerce\'s account menu items as the theme\'s rows, grouped through the filter rooster/account/menu_groups (the portal plugin answers Account, Partner, Tools, Knowledge base). Nothing for a guest.', 'keywords' => array( 'account', 'navigation', 'my account', 'portal', 'menu', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array(), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'notice' => 'The rows come from WooCommerce\'s account menu and the plugins\' groups; nothing to set here.', ), 'render' => 'file:./render.php', ), 'action' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/action', 'version' => '2.0.0', 'title' => 'Call to action', 'category' => 'theme', 'icon' => 'megaphone', 'description' => 'A call to action: a dark panel with the family\'s glow (a band or centred), the brand\'s soft wash, the ink with large buttons; or a row of large buttons with its small print.', 'keywords' => array( 'cta', 'call to action', 'buttons', 'panel', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'panel', 'buttons', ), 'default' => 'panel', ), 'layout' => array( 'type' => 'string', 'enum' => array( '', 'band', 'center', 'wash', 'ink', ), 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'icon' => array( 'type' => 'string', 'default' => '', ), 'eyebrow' => array( 'type' => 'string', 'default' => '', ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'buttons' => array( 'type' => 'string', 'default' => '', ), 'note' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 2, ), 'justify' => array( 'type' => 'string', 'enum' => array( 'center', 'left', ), 'default' => 'center', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'variants' => array( 'panel', 'buttons', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'layout' => array( 'label' => 'Layout inside the variant (empty: the variant\'s first)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s (wash: the tone\'s wash, rule and accents; empty: the brand\'s)', ), 'icon' => array( 'label' => 'panel: Icon before the eyebrow or the heading, in a chip of the tone (a Lucide slug; empty: none)', ), 'eyebrow' => array( 'label' => 'panel: Eyebrow', ), 'heading' => array( 'label' => 'panel: Heading', ), 'text' => array( 'control' => 'textarea', 'label' => 'panel: Text (wash: paragraphs by a blank line, **bold** allowed)', ), 'items' => array( 'control' => 'textarea', 'label' => 'panel: Ticked items, one per line', ), 'buttons' => array( 'control' => 'textarea', 'label' => 'panel: Buttons, one per line: Text | link | primary or secondary (ink: Text | link | download, dark or light | second line | icon); buttons: Buttons, one per line: Text | link | download, dark or light | second line | icon', ), 'note' => array( 'control' => 'textarea', 'label' => 'panel: Small print under the buttons (ink; **bold** allowed)', ), 'level' => array( 'label' => 'panel: Heading level (2 to 4)', ), 'justify' => array( 'label' => 'buttons: Place', ), ), ), 'render' => 'file:./render.php', ), 'announcement-bar' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/announcement-bar', 'version' => '1.1.0', 'title' => 'Announcement bar', 'category' => 'theme', 'icon' => 'megaphone', 'description' => 'The site-wide announcement from Appearance → Rooster Zero (message, link, dismissible). Renders nothing while the message is empty, so it can live in the header part permanently.', 'keywords' => array( 'notice', 'promo', 'strip', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'showIcon' => array( 'type' => 'boolean', 'default' => false, ), ), 'supports' => array( 'html' => false, 'align' => array( 'full', ), 'color' => array( 'background' => true, 'text' => true, 'link' => true, ), 'typography' => array( 'fontSize' => true, 'fontWeight' => true, ), 'spacing' => array( 'padding' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'showIcon' => array( 'label' => 'Show the megaphone icon', ), ), 'notice' => 'The message, link and dismissal are set once in Appearance → Rooster Zero → General.', ), 'render' => 'file:./render.php', ), 'appearance' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/appearance', 'version' => '1.0.0', 'title' => 'Appearance controls', 'category' => 'theme', 'icon' => 'admin-appearance', 'description' => 'Lets visitors choose the theme (light, dark or their device\'s), the text size and a wide layout, remembered in their browser. In the header it opens from an icon; in a menu it shows its buttons directly. The General settings choose which controls it offers.', 'keywords' => array( 'dark mode', 'theme', 'text size', 'accessibility', 'width', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'display' => array( 'type' => 'string', 'enum' => array( 'menu', 'panel', ), 'default' => 'menu', ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'display' => array( 'control' => 'select', 'label' => 'Display', 'options' => array( 'menu' => 'An icon that opens the controls', 'panel' => 'The controls themselves', ), ), ), ), 'render' => 'file:./render.php', ), 'builder-location' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/builder-location', 'version' => '1.0.0', 'title' => 'Builder location', 'category' => 'theme', 'icon' => 'layout', 'description' => 'Where a page builder may take over. In Elementor Compatibility Mode the header and footer locations show the Elementor Pro location or the Header Footer Elementor template that matches the page, and the content location renders an Elementor library template; otherwise the blocks inside render as they are.', 'keywords' => array( 'elementor', 'header', 'footer', 'location', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'location' => array( 'type' => 'string', 'enum' => array( 'header', 'footer', 'content', ), 'default' => 'header', ), 'templateId' => array( 'type' => 'integer', 'default' => 0, ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'innerBlocks' => true, 'when' => 'elementor', 'ui' => array( 'location' => array( 'label' => 'Location', ), 'templateId' => array( 'label' => 'Elementor template ID (content location; 0 = the template the slot resolved to)', ), ), 'notice' => 'Elementor Compatibility Mode is switched in Appearance → Rooster Zero → Elementor. While it is off this block renders its inner blocks only.', ), 'render' => 'file:./render.php', ), 'card' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/card', 'version' => '2.1.0', 'title' => 'Card', 'category' => 'theme', 'icon' => 'index-card', 'description' => 'A card, or a run of cards: one feature or family card from its fields; a grid of icon cards or numbered steps, tagged panels, role cards, link cards, groups that open or category tiles, from one line per card. The variant picks the look, the tone the colour.', 'keywords' => array( 'card', 'cards', 'features', 'family', 'steps', 'grid', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'feature', 'family', 'grid', 'tagged', 'role', 'link', 'detail', 'category', ), 'default' => 'feature', ), 'layout' => array( 'type' => 'string', 'enum' => array( '', 'stack', 'row', 'card', 'tile', 'links', 'banner', 'cards', 'steps', 'steps-plain', 'panels', 'numbered', 'palettes', ), 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'icon' => array( 'type' => 'string', 'default' => 'award', ), 'title' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'ctaText' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 3, ), 'badge' => array( 'type' => 'string', 'default' => '', ), 'kicker' => array( 'type' => 'string', 'default' => '', ), 'highlighted' => array( 'type' => 'boolean', 'default' => false, ), 'price' => array( 'type' => 'string', 'default' => '', ), 'family' => array( 'type' => 'string', 'default' => '', ), 'name' => array( 'type' => 'string', 'default' => '', ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'products' => array( 'type' => 'string', 'default' => '', ), 'features' => array( 'type' => 'string', 'default' => '', ), 'docsHref' => array( 'type' => 'string', 'default' => '', ), 'docsText' => array( 'type' => 'string', 'default' => '', ), 'motif' => array( 'type' => 'string', 'default' => '', ), 'columns' => array( 'type' => 'string', 'default' => '3', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'unit' => array( 'type' => 'string', 'default' => '', ), 'swatches' => array( 'type' => 'string', 'default' => '', ), 'rule' => array( 'type' => 'string', 'enum' => array( '', 'side', ), 'default' => '', ), 'border' => array( 'type' => 'string', 'enum' => array( '', 'strong', 'accent', ), 'default' => '', ), 'chips' => array( 'type' => 'string', 'default' => '', ), 'chipsLayout' => array( 'type' => 'string', 'enum' => array( 'tiles', 'pills', 'lines', ), 'default' => 'tiles', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', 'full', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '480px', ), ), ), 'rooster' => array( 'variants' => array( 'feature', 'family', 'grid', 'tagged', 'role', 'link', 'detail', 'category', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'layout' => array( 'label' => 'Layout inside the variant (empty: the variant\'s first)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'icon' => array( 'control' => 'icon', 'label' => 'feature: Icon (none: no icon)', ), 'text' => array( 'control' => 'textarea', 'label' => 'feature: Text (a blank line starts a paragraph; lines starting with - make a list); family: Text (the tagline; a banner\'s lede)', ), 'href' => array( 'control' => 'url', 'label' => 'feature: Link; family: The family\'s page', ), 'ctaText' => array( 'label' => 'feature: Link text (empty: the title is the link); family: Link text (Explore …)', ), 'level' => array( 'label' => 'feature: Heading level (2 to 4); family: Heading level (2 to 4); grid: Heading level (2 to 4); tagged: Heading level of the titles; role: Heading level of the questions', ), 'badge' => array( 'label' => 'feature: Badge (New, Pro, a step number)', ), 'kicker' => array( 'label' => 'feature: Kicker (a short line above the title)', ), 'highlighted' => array( 'label' => 'feature: Highlighted (the accent on the border)', ), 'price' => array( 'label' => 'feature: Price line', ), 'family' => array( 'label' => 'family: Family (the accent\'s slug: zero, one, lms, panel…)', ), 'name' => array( 'label' => 'family: Name (the wordmark; the eyebrow of a banner)', ), 'heading' => array( 'label' => 'family: Heading (a banner\'s)', ), 'products' => array( 'control' => 'textarea', 'label' => 'family: Products, one per line: Name | link | badge | line (a banner\'s buttons: Text | link)', ), 'features' => array( 'control' => 'textarea', 'label' => 'family: Features, one per line: Text | link', ), 'docsHref' => array( 'control' => 'url', 'label' => 'family: Documentation link', ), 'docsText' => array( 'label' => 'family: Documentation link text', ), 'motif' => array( 'label' => 'family: Illustration (a pattern\'s slug: rooster-site/motif-zero)', ), 'columns' => array( 'label' => 'grid: Columns on a computer (2, 3 or 4: four from 64rem, two from 48rem; steps follow their count); tagged: Columns (panels): three, two, or wide beside narrow', ), 'items' => array( 'control' => 'textarea', 'label' => 'grid: One card per line: icon | Title | Text | tone (the tone a family\'s slug or neutral, success, warning, danger; the icon none: no chip) (steps: Title | Text | tone | mark:icon, the tone filling the disc, the mark an icon in place of the number; both optional, either order); after the text, in any order: anchor: (the card\'s id) and link:[text](url) (a link on its own line under the text); tagged: Cards: a line `# Tag | green, red, amber or blue | Title | top, edge, pos or neg` starts each; then paragraphs, `- ` list items, `~ chip | chip` chips (`~! chip` for the one that stands out); **bold** and `code` allowed; role: Roles, one per line: icon | Name | Question | Line | #colour; link: One card per line: Name | line | link; detail: A card per # line (# Name | icon), then its entries, one per line: Name | line; category: One tile per line: picture (an image id) | category (a product category\'s slug or id) | area (lacquer, plum, coral, blush or nude) | name (else the category\'s)', ), 'unit' => array( 'label' => 'detail: What an entry is, singular|plural (screen|screens)', ), 'swatches' => array( 'control' => 'textarea', 'label' => 'family palettes: one palette per line, Name | #background | #text | #accent', ), 'rule' => array( 'label' => 'feature, grid: Rule: side (a 4 px stripe at each card\'s start in its tone)', ), 'border' => array( 'label' => 'feature, grid: Border: strong (the Pro cards\' grey) or accent', ), 'chips' => array( 'control' => 'textarea', 'label' => 'feature: Chips after the text, one per line: icon | Text, or Text alone (the list\'s chips, in the card\'s tone)', ), 'chipsLayout' => array( 'label' => 'feature: The chips\' layout: tiles, pills (no icon) or lines', ), ), ), 'render' => 'file:./render.php', ), 'cart-badge' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/cart-badge', 'version' => '1.0.0', 'title' => 'Cart badge', 'category' => 'theme', 'icon' => 'cart', 'description' => 'Cart icon with the item count, hydrated from the Store API after the first human interaction so guest pages stay fully cacheable. Opens Rooster One\'s side cart (rooster:cart:open) when present, else links to the cart.', 'keywords' => array( 'cart', 'basket', 'badge', 'count', 'header', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'icon' => array( 'type' => 'string', 'enum' => array( 'cart', 'bag', ), 'default' => 'bag', ), 'showZero' => array( 'type' => 'boolean', 'default' => false, ), 'label' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'color' => array( 'background' => true, 'text' => true, ), 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'icon' => array( 'control' => 'icon', 'label' => 'Icon', ), 'showZero' => array( 'label' => 'Show the badge when the cart is empty', ), 'label' => array( 'label' => 'Accessible label (defaults to “Cart”)', ), ), ), 'render' => 'file:./render.php', 'viewScriptModule' => 'file:./view.min.js', ), 'consent' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/consent', 'version' => '1.0.0', 'title' => 'Cookie consent', 'category' => 'theme', 'icon' => 'privacy', 'description' => 'A cookie consent banner that lives in the deferred layer (never in the first HTML), stores the choice in one record (rooster_consent) and fires rooster:consent:changed, which gates every third-party script registered with the theme.', 'keywords' => array( 'cookie', 'consent', 'gdpr', 'privacy', 'banner', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'heading' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'showChoices' => array( 'type' => 'boolean', 'default' => true, ), 'position' => array( 'type' => 'string', 'enum' => array( 'bottom', 'bottom-left', 'center', ), 'default' => 'bottom', ), 'buttonCorner' => array( 'type' => 'string', 'enum' => array( 'start', 'end', ), 'default' => 'start', ), ), 'supports' => array( 'html' => false, 'color' => array( 'background' => true, 'text' => true, ), 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '0px', 'default' => 'layer', ), ), ), 'rooster' => array( 'ui' => array( 'text' => array( 'control' => 'textarea', 'label' => 'Text (a link to the privacy policy is added automatically)', ), 'showChoices' => array( 'label' => 'Offer per-category choices (functional, analytics, marketing)', ), 'position' => array( 'label' => 'Position', ), 'buttonCorner' => array( 'label' => 'Cookie preferences button: the start corner (left) or the end corner (right, beside a chat)', ), ), 'notice' => 'Place it once, in the footer part. It renders only after the first human interaction, as an overlay, so it never shifts the page or loads for crawlers.', ), 'render' => 'file:./render.php', 'viewScriptModule' => 'file:./view.min.js', ), 'docs-breadcrumb' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster-docs/breadcrumb', 'version' => '1.0.0', 'title' => 'Manual breadcrumb', 'category' => 'theme', 'icon' => 'ellipsis', 'description' => 'The path from the language root to the chapter, then the page\'s title (the manuals\' templates).', 'keywords' => array( 'manual', 'documentation', 'breadcrumb', 'docs', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array(), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'notice' => 'The path comes from the manual\'s categories; nothing to set here.', ), 'render' => 'file:./render.php', ), 'docs-chapters' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster-docs/chapters', 'version' => '1.0.0', 'title' => 'Manual chapters', 'category' => 'theme', 'icon' => 'book', 'description' => 'A manual\'s chapter tree beside its pages (the manuals\' templates): the manual\'s name, its own pages, the chapters in the publishing pipeline\'s order with the current one open, the other chapters\' pages brought in on first intent, a filter box, and the sidebar\'s scroll position remembered across pages.', 'keywords' => array( 'manual', 'documentation', 'chapters', 'table of contents', 'docs', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'filter' => array( 'type' => 'boolean', 'default' => true, ), 'remember' => array( 'type' => 'boolean', 'default' => true, ), ), 'supports' => array( 'html' => false, 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'filter' => array( 'label' => 'The filter box', ), 'remember' => array( 'label' => 'Remember the scroll position across pages', ), ), ), 'style' => 'file:./style.css', 'viewScriptModule' => 'file:./view.min.js', 'render' => 'file:./render.php', ), 'docs-download' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster-docs/download', 'version' => '1.0.0', 'title' => 'Manual download card', 'category' => 'theme', 'icon' => 'download', 'description' => 'The card under a manual\'s chapters that leads to the product (the Get the plugin card: wordpress.org for the Rooster One and Rooster LMS manuals). The texts come from the manual (AIEO_Docs::card()) unless set here. No DOCX: the legacy site had none.', 'keywords' => array( 'manual', 'documentation', 'download', 'get the plugin', 'docs', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'title' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'cta' => array( 'type' => 'string', 'default' => '', ), 'sub' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'badge' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'title' => array( 'label' => 'Title (empty: the manual\'s)', ), 'text' => array( 'control' => 'textarea', 'label' => 'Text', ), 'cta' => array( 'label' => 'Button text', ), 'sub' => array( 'label' => 'Line under the button text', ), 'href' => array( 'control' => 'url', 'label' => 'Link', ), 'badge' => array( 'label' => 'Line under the button', ), ), ), 'style' => 'file:./style.css', 'render' => 'file:./render.php', ), 'docs-quote' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster-docs/quote', 'version' => '1.0.0', 'title' => 'Manual quote card', 'category' => 'theme', 'icon' => 'email', 'description' => 'The card under a manual\'s chapters that asks for a quote (Evit for LANSA\'s form on /lansa/#quote). The texts come from the manual (AIEO_Docs::card()) unless set here.', 'keywords' => array( 'manual', 'documentation', 'quote', 'lansa', 'docs', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'title' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'cta' => array( 'type' => 'string', 'default' => '', ), 'sub' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'badge' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'title' => array( 'label' => 'Title (empty: the manual\'s)', ), 'text' => array( 'control' => 'textarea', 'label' => 'Text', ), 'cta' => array( 'label' => 'Button text', ), 'sub' => array( 'label' => 'Line under the button text', ), 'href' => array( 'control' => 'url', 'label' => 'Link', ), 'badge' => array( 'label' => 'Line under the button', ), ), ), 'style' => 'file:./style.css', 'render' => 'file:./render.php', ), 'header-link' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/header-link', 'version' => '1.0.1', 'title' => 'Header link', 'category' => 'theme', 'icon' => 'admin-links', 'description' => 'A link in the header actions\' look (contract C11): an icon from the theme\'s set and a text, shown beside it on computers when the block says so. For a store finder, contact or help.', 'keywords' => array( 'header', 'link', 'icon', 'stores', 'contact', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'label' => array( 'type' => 'string', 'default' => '', ), 'url' => array( 'type' => 'string', 'default' => '', ), 'icon' => array( 'type' => 'string', 'default' => 'map-pin', ), 'newTab' => array( 'type' => 'boolean', 'default' => false, ), 'showText' => array( 'type' => 'boolean', 'default' => false, ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'label' => array( 'label' => 'Text (also the link\'s name for screen readers)', ), 'url' => array( 'control' => 'url', 'label' => 'Link', ), 'icon' => array( 'control' => 'icon', 'label' => 'Icon', ), 'newTab' => array( 'label' => 'Open in a new tab', ), 'showText' => array( 'label' => 'Show the text beside the icon on computers', ), ), ), 'render' => 'file:./render.php', ), 'language-switcher' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/language-switcher', 'version' => '1.0.0', 'title' => 'Language switcher', 'category' => 'theme', 'icon' => 'translation', 'description' => 'The site\'s languages from WPML or Polylang, each linking to the translation of the current page. Server-rendered, no script. Shows nothing on a site with one language.', 'keywords' => array( 'language', 'translation', 'multilingual', 'wpml', 'polylang', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'display' => array( 'type' => 'string', 'enum' => array( 'menu', 'list', ), 'default' => 'menu', ), 'label' => array( 'type' => 'string', 'enum' => array( 'code', 'name', ), 'default' => 'code', ), 'flags' => array( 'type' => 'boolean', 'default' => false, ), 'globe' => array( 'type' => 'boolean', 'default' => true, ), ), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'display' => array( 'label' => 'Style: a menu that opens, or a list', ), 'label' => array( 'label' => 'Show each language as its code (EN) or its name (English)', ), 'flags' => array( 'label' => 'Show flags (the multilingual plugin\'s images)', ), 'globe' => array( 'label' => 'Show the globe beside the code in the menu\'s button (off: the code alone, EL)', ), ), ), 'render' => 'file:./render.php', ), 'list' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/list', 'version' => '2.0.0', 'title' => 'List', 'category' => 'theme', 'icon' => 'editor-ul', 'description' => 'Points, figures or steps: ticked lines (two columns, bordered rows, a tinted panel, the manual\'s links), key figures (behind a rule, counters, a tally, bars), a staged process in a panel, or short items (tiles, pills, lines with icons).', 'keywords' => array( 'list', 'checklist', 'facts', 'figures', 'stages', 'chips', 'tiles', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'checks', 'facts', 'stages', 'chips', ), 'default' => 'checks', ), 'layout' => array( 'type' => 'string', 'enum' => array( '', 'grid', 'cards', 'panel', 'links', 'list', 'counters', 'tally', 'bars', 'tiles', 'pills', 'lines', ), 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 3, ), 'text' => array( 'type' => 'string', 'default' => '', ), 'note' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '320px', ), ), ), 'rooster' => array( 'variants' => array( 'checks', 'facts', 'stages', 'chips', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'layout' => array( 'label' => 'Layout inside the variant (empty: the variant\'s first): checks grid, cards, panel, links; facts list, counters, tally, bars; chips tiles, pills, lines', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'heading' => array( 'label' => 'checks: Heading (the panel\'s); stages: Heading', ), 'items' => array( 'control' => 'textarea', 'label' => 'checks: One item per line (links: Text | link); facts: One figure per line: Value | Label | tone | caption (tone: a family\'s slug or neutral, success, warning, danger, may be empty; caption: a small line over the value); bars: Value | Label | share (0 to 100) | aside; stages: Stages, one per line: Step | tone | Name | Where it runs | Text; chips: One item per line: icon | Text, or Text alone (pills: no icon)', ), 'level' => array( 'label' => 'checks: The panel heading\'s level (2 to 4); stages: Heading level (the stages\' names one under it)', ), 'text' => array( 'control' => 'textarea', 'label' => 'stages: Paragraphs (a blank line between them; **bold** allowed)', ), 'note' => array( 'control' => 'textarea', 'label' => 'stages: Note under the stages', ), ), ), 'render' => 'file:./render.php', ), 'mark' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/mark', 'version' => '2.0.0', 'title' => 'Mark', 'category' => 'theme', 'icon' => 'tag', 'description' => 'A small mark: the family crumb above a title, a pill with an icon above a heading, a note set apart, or a bar of linked pills (the page\'s areas).', 'keywords' => array( 'crumb', 'pill', 'note', 'eyebrow', 'nav', 'pills', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'crumb', 'pill', 'note', 'nav', ), 'default' => 'crumb', ), 'layout' => array( 'type' => 'string', 'enum' => array( '', 'card', 'rule', ), 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'family' => array( 'type' => 'string', 'default' => '', ), 'name' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'icon' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'label' => array( 'type' => 'string', 'default' => '', ), 'justify' => array( 'type' => 'string', 'enum' => array( 'center', 'left', ), 'default' => 'center', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'variants' => array( 'crumb', 'pill', 'note', 'nav', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'layout' => array( 'label' => 'Layout inside the variant (empty: the variant\'s first)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'family' => array( 'label' => 'crumb: Family (the accent\'s slug: its name and page come from the theme\'s accents)', ), 'name' => array( 'label' => 'crumb: Name (else the family\'s)', ), 'href' => array( 'control' => 'url', 'label' => 'crumb: Link (else the family\'s page)', ), 'text' => array( 'label' => 'pill: Text; note: Text (**bold** allowed)', ), 'icon' => array( 'label' => 'pill: Icon (a Lucide name: zap)', ), 'items' => array( 'control' => 'textarea', 'label' => 'nav: One pill per line: Text | link | icon | tone (the tone a family\'s slug or neutral, success, warning, danger; empty: the block\'s)', ), 'label' => array( 'label' => 'nav: The bar’s name for a screen reader (empty: On this page)', ), 'justify' => array( 'label' => 'pill: Place', ), ), ), 'render' => 'file:./render.php', ), 'media' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/media', 'version' => '2.0.0', 'title' => 'Picture', 'category' => 'theme', 'icon' => 'format-image', 'description' => 'A picture: a product\'s picture in its square dark frame (or the family\'s illustration), a site on a computer and a phone, a diagram in a hairline frame with its caption, layers drawn on a dark panel, or a strip of figures with its previous and next buttons.', 'keywords' => array( 'picture', 'image', 'screens', 'figure', 'diagram', 'gallery', 'screenshots', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'frame', 'screens', 'figure', 'stack', 'track', ), 'default' => 'frame', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'desktopId' => array( 'type' => 'integer', 'default' => 0, ), 'mobileId' => array( 'type' => 'integer', 'default' => 0, ), 'desktopAlt' => array( 'type' => 'string', 'default' => '', ), 'sizes' => array( 'type' => 'string', 'default' => '', ), 'priority' => array( 'type' => 'string', 'enum' => array( 'auto', 'high', 'low', ), 'default' => 'auto', ), 'motif' => array( 'type' => 'string', 'default' => '', ), 'mobileAlt' => array( 'type' => 'string', 'default' => '', ), 'caption' => array( 'type' => 'string', 'default' => '', ), 'width' => array( 'type' => 'integer', 'default' => 0, ), 'height' => array( 'type' => 'integer', 'default' => 0, ), 'eyebrow' => array( 'type' => 'string', 'default' => '', ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'text' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'label' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 2, ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '480px', ), ), ), 'rooster' => array( 'variants' => array( 'frame', 'screens', 'figure', 'stack', 'track', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'desktopId' => array( 'control' => 'media', 'label' => 'frame: The picture; screens: The computer\'s screenshot; figure: The picture (an SVG drawing or a photograph)', ), 'mobileId' => array( 'control' => 'media', 'label' => 'frame: The phone\'s picture (else the same); screens: The phone\'s screenshot', ), 'desktopAlt' => array( 'label' => 'frame: Alternative text (empty: decorative); screens: Its alternative text; figure: Alternative text', ), 'sizes' => array( 'label' => 'frame: Sizes (the slot\'s widths); figure: Sizes (the cell\'s widths; empty: the page\'s); track: Sizes (empty: the strip\'s)', ), 'priority' => array( 'label' => 'frame: Priority (high for the page\'s first picture)', ), 'motif' => array( 'label' => 'frame: Illustration without a picture (a pattern\'s slug: rooster-site/motif-code)', ), 'mobileAlt' => array( 'label' => 'screens: Its alternative text', ), 'caption' => array( 'control' => 'textarea', 'label' => 'figure: Caption', ), 'width' => array( 'label' => 'figure: Width (px, the drawing\'s own)', ), 'height' => array( 'label' => 'figure: Height (px, the drawing\'s own)', ), 'eyebrow' => array( 'label' => 'stack: Eyebrow', ), 'heading' => array( 'label' => 'stack: Heading', ), 'text' => array( 'control' => 'textarea', 'label' => 'stack: Lede', ), 'items' => array( 'control' => 'textarea', 'label' => 'stack: Layers, one per line: Name | What it does | hi (the one that stands out); track: Figures, one per line: the picture\'s id ({{media-id:…}} in a spec) | Alternative text (empty: the picture\'s) | Caption (**bold** allowed)', ), 'label' => array( 'label' => 'track: The strip\'s name for a screen reader (empty: Pictures)', ), 'level' => array( 'label' => 'stack: Heading level', ), ), ), 'render' => 'file:./render.php', ), 'mega-menu' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/mega-menu', 'version' => '1.2.14', 'title' => 'Mega menu', 'category' => 'theme', 'icon' => 'menu', 'description' => 'A header menu that carries only its top level in the page (one link per entry of the navigation menu named) and brings each entry\'s panel on the first hover, focus or tap from a versioned file of pre-rendered panels, kept in the visitor\'s browser until a menu is saved. An entry whose accent names one of the family menus opens that menu\'s panel (its columns are the menu\'s submenus, with the family\'s tagline, call to action and illustration); an entry with children of its own opens them as a list, or, where its layout is the mega panel, across the page\'s width under the header: its children in columns, a picture card (the image of the category it links to, or an illustration of its own) and a foot row of links and texts at its start and its end, the page dimmed behind it. On a phone the panels open inside a dialog from a menu button: each entry\'s panel under it as an accordion, or one level at a time (drawer: levels).', 'keywords' => array( 'menu', 'navigation', 'mega menu', 'header', 'families', 'lazy', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'navigation' => array( 'type' => 'string', 'default' => 'navigation', ), 'menus' => array( 'type' => 'string', 'default' => '', ), 'intent' => array( 'type' => 'string', 'enum' => array( 'hover', 'focus', 'click', ), 'default' => 'hover', ), 'label' => array( 'type' => 'string', 'default' => '', ), 'drawer' => array( 'type' => 'string', 'enum' => array( 'accordion', 'levels', ), 'default' => 'accordion', ), ), 'supports' => array( 'html' => false, 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'navigation' => array( 'label' => 'The navigation menu (its slug): the top level', ), 'menus' => array( 'label' => 'The family menus (slugs, comma-separated): one panel each', ), 'intent' => array( 'label' => 'Opens on', ), 'label' => array( 'label' => 'Accessible name (empty: Products)', ), 'drawer' => array( 'label' => 'On a phone (accordion: each entry\'s panel under it; levels: one level at a time)', ), ), 'notice' => 'The panels come from the menus\' posts (Appearance, Editor, Navigation); a saved menu is a new version.', ), 'style' => 'file:./style.css', 'viewScriptModule' => 'file:./view.min.js', 'render' => 'file:./render.php', ), 'newsletter-banner' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/newsletter-banner', 'version' => '1.0.0', 'title' => 'Newsletter banner', 'category' => 'theme', 'icon' => 'email-alt', 'description' => 'Full-width banner in the Rooster One layout: art-directed background, logo, heading and intro, the form of your choice as inner blocks, and single sign-on buttons through rooster/newsletter/after_form. With Rooster One active, prefer its Newsletter signup block; this one serves sites without it.', 'keywords' => array( 'newsletter', 'subscribe', 'signup', 'banner', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'desktopBgId' => array( 'type' => 'integer', 'default' => 0, ), 'mobileBgId' => array( 'type' => 'integer', 'default' => 0, ), 'logoId' => array( 'type' => 'integer', 'default' => 0, ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'description' => array( 'type' => 'string', 'default' => '', ), 'glassDesktop' => array( 'type' => 'boolean', 'default' => false, ), 'glassMobile' => array( 'type' => 'boolean', 'default' => true, ), 'privacyText' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'align' => array( 'wide', 'full', ), 'color' => array( 'background' => true, 'text' => true, ), 'spacing' => array( 'padding' => true, 'margin' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '360px', 'default' => 'near', ), ), ), 'rooster' => array( 'innerBlocks' => true, 'template' => array( array( 'core/shortcode', array(), ), ), 'ui' => array( 'desktopBgId' => array( 'control' => 'media', 'label' => 'Background image', ), 'mobileBgId' => array( 'control' => 'media', 'label' => 'Mobile background (optional)', ), 'logoId' => array( 'control' => 'media', 'label' => 'Logo (optional)', ), 'description' => array( 'control' => 'textarea', 'label' => 'Intro', ), 'glassDesktop' => array( 'label' => 'Frosted-glass card on desktop', ), 'glassMobile' => array( 'label' => 'Frosted-glass card on mobile', ), 'privacyText' => array( 'control' => 'textarea', 'label' => 'Privacy line under the form (optional)', ), ), ), 'render' => 'file:./render.php', ), 'plan' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/plan', 'version' => '2.0.0', 'title' => 'Plan', 'category' => 'theme', 'icon' => 'money-alt', 'description' => 'A plan or a price: the price card with its marks, the product plan with the one to pick ringed, or the tier led by its toned tag with its volume table. Never deferred: prices are content people search for.', 'keywords' => array( 'plan', 'price', 'pricing', 'tier', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'price', 'plan', ), 'default' => 'price', ), 'layout' => array( 'type' => 'string', 'enum' => array( '', 'card', 'row', 'tier', ), 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'name' => array( 'type' => 'string', 'default' => '', ), 'tagline' => array( 'type' => 'string', 'default' => '', ), 'price' => array( 'type' => 'string', 'default' => '', ), 'period' => array( 'type' => 'string', 'default' => '', ), 'note' => array( 'type' => 'string', 'default' => '', ), 'features' => array( 'type' => 'string', 'default' => '', ), 'ctaText' => array( 'type' => 'string', 'default' => '', ), 'ctaHref' => array( 'type' => 'string', 'default' => '', ), 'highlighted' => array( 'type' => 'boolean', 'default' => false, ), 'badge' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 3, ), 'volume' => array( 'type' => 'string', 'default' => '', ), 'volumeCaption' => array( 'type' => 'string', 'default' => '', ), 'volumeNote' => array( 'type' => 'string', 'default' => '', ), 'ctaStyle' => array( 'type' => 'string', 'enum' => array( 'primary', 'outline', ), 'default' => 'primary', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'variants' => array( 'price', 'plan', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'layout' => array( 'label' => 'Layout inside the variant (empty: the variant\'s first)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'name' => array( 'label' => 'price: Plan name; plan: Name', ), 'tagline' => array( 'label' => 'price: Tagline (a line under the name); plan: a line under the name (card), the tier\'s heading (tier)', ), 'price' => array( 'label' => 'price: Price (as shown, with the currency); plan: Price', ), 'period' => array( 'label' => 'price: Period (per month, forever); plan: Period (a month)', ), 'note' => array( 'label' => 'price: Note under the price; plan: Note (or $190 a year)', ), 'features' => array( 'control' => 'textarea', 'label' => 'price: Features, one per line (a leading - marks one not included); plan: Features, one per line (a line ## Name: a group\'s heading over the lines that follow)', ), 'ctaText' => array( 'label' => 'price: Button text; plan: Button text', ), 'ctaHref' => array( 'control' => 'url', 'label' => 'price: Button link; plan: Button link', ), 'highlighted' => array( 'label' => 'price: Highlighted (the plan to pick); plan: Ringed, the plan to pick (card and tier)', ), 'badge' => array( 'label' => 'price: Badge (Most popular); plan: Its badge over the ring (card and tier; none without one)', ), 'level' => array( 'label' => 'Heading level (2 to 6): the name\'s (price, plan card), the tier\'s heading', ), 'volume' => array( 'control' => 'textarea', 'label' => 'plan: Tier\'s volume table: one row per line, cells by bars, the first the head', ), 'volumeCaption' => array( 'label' => 'plan: Over the volume table', ), 'volumeNote' => array( 'control' => 'textarea', 'label' => 'plan: Under the volume table', ), 'ctaStyle' => array( 'label' => 'plan: Tier\'s button: filled or outlined', ), ), ), 'render' => 'file:./render.php', ), 'promo-tile' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/promo-tile', 'version' => '1.0.0', 'title' => 'Promo tile', 'category' => 'theme', 'icon' => 'megaphone', 'description' => 'Art-directed image, heading, text and a call to action; optionally shown to selected roles only.', 'keywords' => array( 'promo', 'banner', 'cta', 'tile', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'imageId' => array( 'type' => 'integer', 'default' => 0, ), 'mobileId' => array( 'type' => 'integer', 'default' => 0, ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'body' => array( 'type' => 'string', 'default' => '', ), 'ctaText' => array( 'type' => 'string', 'default' => '', ), 'ctaHref' => array( 'type' => 'string', 'default' => '', ), 'roles' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'align' => array( 'wide', 'full', ), 'color' => array( 'background' => true, 'text' => true, ), 'spacing' => array( 'padding' => true, 'margin' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '320px', 'default' => 'inline', ), ), ), 'rooster' => array( 'ui' => array( 'imageId' => array( 'control' => 'media', 'label' => 'Image', ), 'mobileId' => array( 'control' => 'media', 'label' => 'Mobile image (optional)', ), 'body' => array( 'control' => 'textarea', 'label' => 'Text', ), 'ctaText' => array( 'label' => 'Button text', ), 'ctaHref' => array( 'control' => 'url', 'label' => 'Button link', ), 'roles' => array( 'label' => 'Show only to roles (comma-separated; pages with role-gated tiles are not cacheable)', ), ), ), 'render' => 'file:./render.php', ), 'questions' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/questions', 'version' => '2.0.1', 'title' => 'Questions', 'category' => 'theme', 'icon' => 'editor-help', 'description' => 'Questions and their answers, each question a row that opens its answer: rows divided by a hairline, or each in its own rounded box, the first open.', 'keywords' => array( 'faq', 'questions', 'answers', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'rows', 'boxed', ), 'default' => 'rows', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'open' => array( 'type' => 'string', 'enum' => array( '', 'first', ), 'default' => '', ), 'anchorPrefix' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '560px', ), ), ), 'rooster' => array( 'ui' => array( 'variant' => array( 'label' => 'Variant (rows: divided by a hairline; boxed: each in its own box, the first open)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'items' => array( 'control' => 'textarea', 'label' => 'One question per line: Question | Answer; a line without a bar continues the answer above it as a further paragraph (a question without an answer: Question |); **bold**, `code` and // allowed in answers', ), 'open' => array( 'label' => 'rows: Open the first question (first; the boxed variant always does)', ), 'anchorPrefix' => array( 'label' => 'rows: Anchors (each question\'s id is the prefix and its number; empty: none)', ), ), ), 'style' => 'rooster-lib-questions', 'render' => 'file:./render.php', ), 'recaptcha-form' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/recaptcha-form', 'version' => '2.0.0', 'title' => 'Form with reCAPTCHA on demand', 'category' => 'theme', 'icon' => 'shield', 'description' => 'Wrap any form block in it. Rooster One\'s form protection guards the forms inside and loads reCAPTCHA itself; a form plugin\'s own reCAPTCHA loads on the first focus or tap inside the form, never on page load and never for crawlers.', 'keywords' => array( 'form', 'recaptcha', 'captcha', 'spam', 'contact', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'note' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'align' => array( 'wide', ), 'spacing' => array( 'padding' => true, 'margin' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '320px', 'default' => 'inline', ), ), ), 'rooster' => array( 'innerBlocks' => true, 'ui' => array( 'note' => array( 'control' => 'textarea', 'label' => 'Small print shown under the form (for example the reCAPTCHA notice)', ), ), ), 'render' => 'file:./render.php', ), 'responsive-image' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/responsive-image', 'version' => '1.0.0', 'title' => 'Responsive image', 'category' => 'media', 'icon' => 'format-image', 'description' => 'A picture that opens a page: a file for computers (an SVG stays as it is) and one for phones, from which the block makes its WebP sizes and serves each screen the one it needs, sized, titled and preloaded as the page\'s first paint; beside either, an SVG of the same picture as its sharp version, which a sharp screen takes after the first interaction. The LCP primitive for heroes and banners.', 'keywords' => array( 'picture', 'hero', 'banner', 'art direction', 'webp', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'desktopId' => array( 'type' => 'integer', 'default' => 0, ), 'desktopAlt' => array( 'type' => 'string', 'default' => '', ), 'mobileId' => array( 'type' => 'integer', 'default' => 0, ), 'mobileAlt' => array( 'type' => 'string', 'default' => '', ), 'decorative' => array( 'type' => 'boolean', 'default' => false, ), 'desktopVectorId' => array( 'type' => 'integer', 'default' => 0, ), 'mobileVectorId' => array( 'type' => 'integer', 'default' => 0, ), 'title' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'sizes' => array( 'type' => 'string', 'default' => '', ), 'priority' => array( 'type' => 'string', 'enum' => array( 'auto', 'high', 'low', ), 'default' => 'auto', ), 'loading' => array( 'type' => 'string', 'enum' => array( 'auto', 'lazy', 'eager', ), 'default' => 'auto', ), 'breakpoint' => array( 'type' => 'integer', 'default' => 782, ), 'rounded' => array( 'type' => 'boolean', 'default' => true, ), 'desktopAspectRatio' => array( 'type' => 'string', 'default' => '', ), 'mobileAspectRatio' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'align' => array( 'wide', 'full', ), 'spacing' => array( 'margin' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'desktopId' => array( 'control' => 'media', 'label' => 'Image for computers (an SVG stays as it is; a raster gets WebP sizes)', ), 'mobileId' => array( 'control' => 'media', 'label' => 'Image for phones (a raster; the block makes its WebP sizes; empty: the computers\' image)', ), 'desktopVectorId' => array( 'control' => 'media', 'label' => 'Sharp version for computers (an SVG of the same picture: the image above paints first, small, and a sharp screen takes the SVG after the visitor\'s first touch, scroll or key)', ), 'mobileVectorId' => array( 'control' => 'media', 'label' => 'Sharp version for phones (an SVG of the phone image, the same way; empty: the computers\' sharp version when the phones show the computers\' image)', ), 'title' => array( 'label' => 'Title, the tooltip (empty: the image\'s title)', ), 'desktopAlt' => array( 'label' => 'Text alternative (empty: the image\'s, else the title)', ), 'mobileAlt' => array( 'label' => 'Text alternative of the phone image (empty: the same)', ), 'decorative' => array( 'label' => 'Decorative: an empty text alternative (alt="") and no title, whatever the image\'s own; for a picture the text beside it already says', ), 'href' => array( 'control' => 'url', 'label' => 'Link', ), 'sizes' => array( 'label' => 'Sizes (empty: from the alignment)', 'placeholder' => '(max-width: 781px) calc(100vw - 32px), 1280px', ), 'priority' => array( 'label' => 'Fetch priority (auto: high for the first picture on the page)', ), 'loading' => array( 'label' => 'Loading (auto: eager for the first picture on the page, lazy after it)', ), 'breakpoint' => array( 'label' => 'Phones up to (px)', ), 'rounded' => array( 'label' => 'The media corners', ), 'desktopAspectRatio' => array( 'placeholder' => '16/9', ), 'mobileAspectRatio' => array( 'placeholder' => '4/5', ), ), ), 'render' => 'file:./render.php', ), 'route-content' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/route-content', 'version' => '1.0.0', 'title' => 'Route content', 'category' => 'theme', 'icon' => 'layout', 'description' => 'What a route slot renders (contract C3@2): a plugin\'s screen at an address of its own, printed inside the theme\'s route template. In the editor, where no route is current, a note.', 'keywords' => array( 'route', 'screen', 'application', 'portal', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array(), 'supports' => array( 'html' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'notice' => 'The content is the route\'s own; nothing to set here.', ), 'render' => 'file:./render.php', ), 'share-box' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/share-box', 'version' => '1.2.0', 'title' => 'Share box', 'category' => 'theme', 'icon' => 'share', 'description' => 'Share the current post or product: Facebook, X, Pinterest, WhatsApp, email and copy link. No inline script.', 'keywords' => array( 'share', 'social', 'copy link', ), 'textdomain' => 'ai-eshop-optimizer', 'usesContext' => array( 'postId', 'postType', ), 'attributes' => array( 'heading' => array( 'type' => 'string', 'default' => '', ), 'channels' => array( 'type' => 'string', 'default' => 'facebook,x,pinterest,whatsapp,email,copy', ), 'display' => array( 'type' => 'string', 'enum' => array( 'inline', 'popover', 'column', ), 'default' => 'inline', ), 'showHeading' => array( 'type' => 'boolean', ), 'favourite' => array( 'type' => 'boolean', 'default' => false, ), ), 'supports' => array( 'html' => false, 'align' => array( 'wide', ), 'color' => array( 'background' => true, 'text' => true, ), 'spacing' => array( 'padding' => true, 'margin' => true, ), 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '56px', 'default' => 'inline', ), ), ), 'rooster' => array( 'ui' => array( 'heading' => array( 'label' => 'Heading (defaults to “Share”)', ), 'channels' => array( 'label' => 'Channels, comma-separated: facebook, x, pinterest, whatsapp, email, copy', ), 'display' => array( 'label' => 'Display: inline (the channels in a row), popover (one share button opening them) or column (Copy link first and two channels at most, beside the text on a computer, a row on a phone)', ), 'showHeading' => array( 'label' => 'Show the heading over the channels (default: in a row yes, in the popover no)', ), 'favourite' => array( 'label' => 'The post\'s heart first (Rooster One\'s Favourite: the same list as Favourites)', ), ), ), 'render' => 'file:./render.php', 'viewScriptModule' => 'file:./view.min.js', ), 'tab' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/tab', 'version' => '1.0.0', 'title' => 'Tab', 'category' => 'theme', 'icon' => 'excerpt-view', 'description' => 'One panel of a Tabs block: its tab\'s words, icon and tone, and the blocks the panel shows. The Tabs block decides which panel shows.', 'keywords' => array( 'tab', 'panel', ), 'textdomain' => 'ai-eshop-optimizer', 'parent' => array( 'rooster/tabs', ), 'attributes' => array( 'label' => array( 'type' => 'string', 'default' => '', ), 'icon' => array( 'type' => 'string', 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'reusable' => false, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'innerBlocks' => true, 'template' => array( array( 'core/paragraph', array(), ), ), 'ui' => array( 'label' => array( 'label' => 'The tab\'s words', ), 'icon' => array( 'control' => 'icon', 'label' => 'Icon before the words (a Lucide name)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the Tabs block\'s', ), ), ), 'render' => 'file:./render.php', ), 'table' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/table', 'version' => '2.0.1', 'title' => 'Table', 'category' => 'theme', 'icon' => 'editor-table', 'description' => 'A table: plans compared with yes, no, soon and partial marks, in toned groups; a data table in a rounded, scrollable frame, rows in their tones; or a matrix of areas joined by hairlines, each in its colour.', 'keywords' => array( 'table', 'compare', 'matrix', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'variant' => array( 'type' => 'string', 'enum' => array( 'compare', 'data', 'matrix', ), 'default' => 'compare', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'columns' => array( 'type' => 'string', 'default' => 'Feature | Free | Pro', ), 'rows' => array( 'type' => 'string', 'default' => '', ), 'marks' => array( 'type' => 'string', 'default' => '', ), 'highlight' => array( 'type' => 'string', 'default' => '', ), 'caption' => array( 'type' => 'string', 'default' => '', ), 'note' => array( 'type' => 'string', 'default' => '', ), 'phone' => array( 'type' => 'string', 'enum' => array( 'stack', 'scroll', ), 'default' => 'stack', ), 'label' => array( 'type' => 'string', 'default' => '', ), 'items' => array( 'type' => 'string', 'default' => '', ), 'level' => array( 'type' => 'integer', 'default' => 3, ), ), 'supports' => array( 'html' => false, 'anchor' => true, 'align' => array( 'wide', ), 'spacing' => array( 'margin' => array( 'top', 'bottom', ), ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '480px', 'default' => 'near', ), ), ), 'rooster' => array( 'variants' => array( 'compare', 'data', 'matrix', ), 'ui' => array( 'variant' => array( 'label' => 'Variant (the look)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s', ), 'columns' => array( 'label' => 'compare: Columns, separated by | (the first is the feature column); data: Columns: Heading | Heading | …', ), 'rows' => array( 'control' => 'textarea', 'label' => 'compare: Rows, one per line, cells separated by | (a cell is yes, no, soon, partial, one of those with a note in brackets, or text with **bold**, `code` and // for a line break; a line # Name | icon | tone is a group heading row, its icon and tone optional; a row with only its first cell is a group heading too); data: One row per line: Name | value | … (yes, no, a dash or words), a last cell more than the columns a tone (a family\'s slug or neutral, success, warning, danger)', ), 'marks' => array( 'label' => 'compare: The marks\' words: Yes words | No words | Soon words | Partial words (empty: Yes, No, Soon, Partial; the soon words are the pill\'s)', ), 'highlight' => array( 'label' => 'compare: Columns to emphasise, their numbers from the left, the feature column being 0 (2, or 2, 3, 4; empty for none)', ), 'caption' => array( 'label' => 'compare: Caption', ), 'note' => array( 'control' => 'textarea', 'label' => 'compare: Note under the table', ), 'phone' => array( 'label' => 'compare: On phones (stack: one section per plan; scroll: the table in a scroll region)', ), 'label' => array( 'label' => 'compare, data: The scroll region\'s name (compare: the caption by default; data: the section\'s heading)', ), 'items' => array( 'control' => 'textarea', 'label' => 'matrix: Areas, one per line: Tag | green, red, amber or blue | Name | Line | #rule | #name | #name in the dark | wide', ), 'level' => array( 'label' => 'matrix: Heading level of the names', ), ), ), 'render' => 'file:./render.php', ), 'tabs' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/tabs', 'version' => '1.1.0', 'title' => 'Tabs', 'category' => 'theme', 'icon' => 'index-card', 'description' => 'Panels behind a row of tabs: a click shows a panel right under the tabs. The server prints the final state (the first tab selected, the other panels hidden until found), so the first paint is the final paint; find in page and a link to anything inside a panel open it. A heading may share the tabs\' row; the outline look is the designer\'s direction B; even panels keep one height, so a switch moves nothing below.', 'keywords' => array( 'tabs', 'panels', 'areas', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'label' => array( 'type' => 'string', 'default' => '', ), 'tone' => array( 'type' => 'string', 'default' => '', ), 'heading' => array( 'type' => 'string', 'default' => '', ), 'headingLevel' => array( 'type' => 'number', 'enum' => array( 2, 3, 4, ), 'default' => 2, ), 'variant' => array( 'type' => 'string', 'enum' => array( '', 'outline', ), 'default' => '', ), 'even' => array( 'type' => 'boolean', 'default' => false, ), ), 'allowedBlocks' => array( 'rooster/tab', ), 'supports' => array( 'html' => false, 'anchor' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'innerBlocks' => true, 'template' => array( array( 'rooster/tab', array( 'label' => 'First', ), ), array( 'rooster/tab', array( 'label' => 'Second', ), ), ), 'ui' => array( 'label' => array( 'label' => 'The tabs\' name for a screen reader (empty: Sections)', ), 'tone' => array( 'label' => 'Tone: A family\'s accent (zero, one, lms, panel, code, docs, kb, credits, lrs) or neutral, success, warning, danger; empty: the page\'s. A tab\'s own tone wins', ), 'heading' => array( 'label' => 'A heading in the tabs\' row, before the tabs, which then name the tab list (empty: none)', ), 'headingLevel' => array( 'label' => 'The heading\'s level (2, 3 or 4)', ), 'variant' => array( 'label' => 'Look: empty, the pills; outline, the designer\'s (direction B): outlined tabs, the selected one in the ink', ), 'even' => array( 'label' => 'Even: the panels keep one height (the tallest), so switching a tab moves nothing below; no find in page inside a hidden panel', ), ), ), 'style' => 'rooster-lib-tabs', 'viewScriptModule' => 'file:./view.min.js', 'render' => 'file:./render.php', ), 'trust-tile' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/trust-tile', 'version' => '1.0.0', 'title' => 'Trust tile', 'category' => 'theme', 'icon' => 'awards', 'description' => 'Icon, title and subtitle from the theme icon collection. Four of them make the store features strip.', 'keywords' => array( 'feature', 'shipping', 'returns', 'guarantee', 'usp', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'icon' => array( 'type' => 'string', 'default' => 'shield', ), 'title' => array( 'type' => 'string', 'default' => '', ), 'subtitle' => array( 'type' => 'string', 'default' => '', ), 'href' => array( 'type' => 'string', 'default' => '', ), 'source' => array( 'type' => 'string', 'default' => '', 'enum' => array( '', 'free_shipping', 'payments', 'hours', ), ), 'look' => array( 'type' => 'string', 'default' => '', 'enum' => array( '', 'plain', ), ), ), 'supports' => array( 'html' => false, 'color' => array( 'background' => true, 'text' => true, ), 'typography' => array( 'fontSize' => true, ), 'spacing' => array( 'padding' => true, 'margin' => true, ), 'rooster' => array( 'defer' => array( 'allowed' => true, 'height' => '96px', 'default' => 'inline', ), ), ), 'rooster' => array( 'ui' => array( 'icon' => array( 'control' => 'icon', 'label' => 'Icon', ), 'subtitle' => array( 'control' => 'textarea', ), 'href' => array( 'control' => 'url', 'label' => 'Link', ), 'source' => array( 'control' => 'select', 'label' => 'Subtitle', 'options' => array( '' => 'The text above', 'free_shipping' => 'The shop\'s free delivery threshold', 'payments' => 'The shop\'s ways to pay', 'hours' => 'The shop\'s opening hours', ), ), 'look' => array( 'control' => 'select', 'label' => 'Look', 'options' => array( '' => 'The icon in a circle', 'plain' => 'A plain icon, aligned with the title', ), ), ), ), 'render' => 'file:./render.php', ), 'view-switch' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/view-switch', 'version' => '1.1.0', 'title' => 'Product view switch', 'category' => 'theme', 'icon' => 'grid-view', 'description' => 'Grid or list: two buttons that show the shop\'s products as a grid or as a list with a short description, and, with Columns set, how many products a row the grid shows on wide screens (3 or 4, remembered for the visitor). Placed in the product collection\'s toolbar, the views load in place.', 'keywords' => array( 'grid', 'list', 'view', 'shop', 'layout', 'columns', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'columns' => array( 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ), ), 'supports' => array( 'html' => false, 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'render' => 'file:./render.php', ), 'wishlist-badge' => array( '$schema' => 'https://schemas.wp.org/trunk/block.json', 'apiVersion' => 3, 'name' => 'rooster/wishlist-badge', 'version' => '1.0.0', 'title' => 'Wishlist badge', 'category' => 'theme', 'icon' => 'heart', 'description' => 'Heart icon with the wishlist count kept by the wishlist provider (rooster:wishlist:changed with detail.count, or the rooster_wishlist_count localStorage key). Opens rooster:wishlist:open when a side cart listens, else links to the wishlist page.', 'keywords' => array( 'wishlist', 'favorites', 'badge', 'header', ), 'textdomain' => 'ai-eshop-optimizer', 'attributes' => array( 'href' => array( 'type' => 'string', 'default' => '', ), 'showZero' => array( 'type' => 'boolean', 'default' => false, ), 'label' => array( 'type' => 'string', 'default' => '', ), ), 'supports' => array( 'html' => false, 'color' => array( 'background' => true, 'text' => true, ), 'interactivity' => true, 'rooster' => array( 'defer' => array( 'allowed' => false, ), ), ), 'rooster' => array( 'ui' => array( 'href' => array( 'control' => 'url', 'label' => 'Wishlist page (defaults to the rooster/wishlist_url filter, or My Account)', ), 'showZero' => array( 'label' => 'Show the badge when the wishlist is empty', ), 'label' => array( 'label' => 'Accessible label (defaults to “Wishlist”)', ), ), ), 'render' => 'file:./render.php', 'viewScriptModule' => 'file:./view.min.js', ), );