Make WordPress Themes

Changeset 356188


Ignore:
Timestamp:
10/29/2026 11:51:56 AM (61 minutes ago)
Author:
themedropbox
Message:

New version of Leitvia - 1.2.11

Location:
leitvia/1.2.11
Files:
18 added
1 deleted
58 edited
1 copied

Legend:

Unmodified
Added
Removed
  • leitvia/1.2.11/assets/css/blocks/core--breadcrumbs.css

    r355111 r356188  
    1 /*
    2  * Breadcrumbs above the h1 of the templates. The separator takes a role color at full strength instead of the
    3  * faded current color of core. Long titles wrap inside their item, so the trail never scrolls sideways at 320 px.
    4  */
    51.wp-block-breadcrumbs {
    62        margin-block-end: var(--wp--preset--spacing--s);
  • leitvia/1.2.11/assets/css/blocks/core--button.css

    r355111 r356188  
    1 /*
    2  * Double focus ring: the outline in focus plus an inner ring in surface that fills the offset gap.
    3  * No single focus color reaches 3:1 on surface, accent and ink at once; on accent and ink sections
    4  * the surface ring carries the contrast (checked by REQUIRED_PAIRS in scripts/lib/contrast.mjs).
    5  */
    61.wp-element-button:focus-visible,
    72.wp-block-button__link:focus-visible {
    … …  
    105        box-shadow: 0 0 0 2px var(--wp--preset--color--surface);
    116}
    12 /* Quiet state changes: color only, never size or shadow. */
    137@media (prefers-reduced-motion: no-preference) {
    148        .wp-element-button,
    … …  
    1711        }
    1812}
    19 /* theme.json style variations have no pseudo states, so the outline hover lives here. */
    2013.wp-block-button.is-style-outline > .wp-block-button__link:hover {
    2114        background-color: var(--wp--preset--color--ink);
    2215        color: var(--wp--preset--color--surface);
    2316}
    24 /*
    25  * On ink and accent bands the default hover (ink fill) would match the band, so buttons turn to surface instead.
    26  * Buttons with their own text color keep the default hover, because preset text color classes cannot be overridden.
    27  */
    2817:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) .wp-block-button__link:not(.has-text-color):hover {
    2918        border-color: var(--wp--preset--color--surface);
    … …  
    3120        color: var(--wp--preset--color--ink);
    3221}
    33 /*
    34  * The fill button is ink, which would vanish on an ink band and on the inverse style, so there it takes the accent
    35  * (on-accent on accent is a checked pair) and turns to surface on hover through the rule above.
    36  */
    3722:is(.has-background.has-ink-background-color, .is-style-inverse) .wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-text-color, .has-background) {
    3823        border-color: var(--wp--preset--color--accent);
    … …  
    4025        color: var(--wp--preset--color--on-accent);
    4126}
    42 /*
    43  * A fill button in the accent color would vanish on an accent band, so there it fills with surface
    44  * and inverts to ink on hover and focus.
    45  */
    4627.has-background.has-accent-background-color .wp-block-button:not(.is-style-outline) > .wp-block-button__link:not(.has-text-color, .has-background) {
    4728        border-color: var(--wp--preset--color--surface);
    … …  
    5435        color: var(--wp--preset--color--surface);
    5536}
     37.wp-block-button__link {
     38        word-break: normal;
     39        overflow-wrap: break-word;
     40}
  • leitvia/1.2.11/assets/css/blocks/core--code.css

    r355111 r356188  
    1 /*
    2  * Terminal: command line look on ink. Long lines scroll instead of wrapping, so commands stay copyable as written.
    3  * functions.php makes the pre focusable, so arrow keys scroll it in every browser.
    4  */
    51.wp-block-code.is-style-terminal {
    62        overflow-x: auto;
    … …  
    1814        outline: 0.125rem solid var(--wp--preset--color--focus);
    1915        outline-offset: 0.125rem;
    20         /* Inner ring for the double focus indicator, see core--button.css. */
    21         box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
     16                box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
    2217}
  • leitvia/1.2.11/assets/css/blocks/core--columns.css

    r355111 r356188  
    1 /* Media right: the first column (usually the image) moves to the end from tablet width up. */
    21@media (min-width: 48.875rem) {
    32        .wp-block-columns.is-style-media-right {
    … …  
    54        }
    65}
     6
     7.wp-block-columns.is-style-overlap > .wp-block-column:last-child {
     8        position: relative;
     9        z-index: 1;
     10}
     11@media (max-width: 48.8125rem) {
     12        .wp-block-columns.is-style-overlap > .wp-block-column:last-child {
     13                margin: calc(var(--wp--preset--spacing--xl) * -1) var(--wp--preset--spacing--s) 0;
     14        }
     15}
     16@media (min-width: 48.875rem) {
     17        .wp-block-columns.is-style-overlap > .wp-block-column:last-child {
     18                flex-grow: 1;
     19                margin-inline-start: calc(var(--wp--preset--spacing--xxl) * -1.5);
     20        }
     21}
  • leitvia/1.2.11/assets/css/blocks/core--cover.css

    r355111 r356188  
    1 /*
    2  * Inverse covers have no overlay color class, because a preset class would fix the overlay to one role in every
    3  * palette. The overlay takes the band color of the inverse style instead (ink in light palettes, surface-alt in
    4  * dark ones); core would paint it black.
    5  */
    61.wp-block-cover.is-style-inverse > .wp-block-cover__background:not([class*="-background-color"]) {
    72        background-color: inherit;
  • leitvia/1.2.11/assets/css/blocks/core--details.css

    r355111 r356188  
    1 /* Replace the browser triangle with a plus or minus sign at the end of the summary. */
    21.wp-block-details > summary {
    32        display: flex;
    … …  
    2221        outline: 0.125rem solid var(--wp--preset--color--focus);
    2322        outline-offset: 0.125rem;
    24         /* Inner ring for the double focus indicator, see core--button.css. */
    25         box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
     23                box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
    2624}
    2725
    28 /*
    29  * Documentation template: the menu is a closed disclosure on small screens and stays open beside the content from
    30  * tablet width on, where the columns sit side by side. Browsers without ::details-content keep the disclosure.
    31  */
    3226@supports selector(::details-content) {
    3327        @media (min-width: 782px) {
  • leitvia/1.2.11/assets/css/blocks/core--group.css

    r355111 r356188  
    1 /*
    2  * Ink, accent and inverse bands: accent links reach only about 1.7 to 3.4:1 on ink and accent, so text links take
    3  * the band text color and stay underlined inside running text. The inverse style is ink in light palettes and
    4  * surface-alt in dark ones, so the band text color is the one choice that passes in both. Navigation, divided lists
    5  * and social links are link-only contexts: no underline at rest, underline on hover and focus. Focus uses the double
    6  * ring from core--button.css. theme.json gives every link the inner ring as well, but with zero specificity; block
    7  * CSS such as social links overrides that, so the rule below stays for the bands.
    8  */
    91:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) a:where(:not(.wp-element-button)),
    102:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) a:where(:not(.wp-element-button)):hover {
    … …  
    2113}
    2214
    23 /*
    24  * Notices: a light tint of the role color over surface and a full hairline frame in the role color. Text stays ink.
    25  * Note uses ink-muted, so it never reads as an error box in palettes with a red accent.
    26  */
    2715.wp-block-group:is(.is-style-note, .is-style-success, .is-style-warning) {
    2816        --leitvia-notice: var(--wp--preset--color--ink-muted);
    … …  
    3927        --leitvia-notice: var(--wp--preset--color--warning);
    4028}
     29
     30.is-style-inverse .wp-block-social-links.is-style-logos-only .wp-social-link {
     31        color: inherit;
     32}
     33
     34.wp-block-group.is-style-header-split {
     35        display: grid;
     36        grid-template-columns: 1fr auto 1fr;
     37        align-items: center;
     38}
     39.is-style-header-split > .wp-block-buttons {
     40        justify-self: end;
     41}
  • leitvia/1.2.11/assets/css/blocks/core--heading.css

    r355111 r356188  
    22        text-wrap: balance;
    33        font-variant-numeric: lining-nums proportional-nums;
     4        overflow-wrap: break-word;
    45}
    5 /* Large headings take the display cut of fonts with an optical size axis (Newsreader); others ignore it. */
    6 :is(h1, h2, .has-heading-m-font-size, .has-heading-l-font-size, .has-display-font-size) {
    7         font-variation-settings: "opsz" 72;
     6:lang(de) .wp-block-heading {
     7        hyphens: auto;
    88}
    99.has-display-font-size:is(h1, h2, h3, p) {
  • leitvia/1.2.11/assets/css/blocks/core--list.css

    r355111 r356188  
    1 /* Divided: no markers, a hairline between items. Used for contact details and short fact lists. */
    2 .wp-block-list.is-style-divided {
     1.wp-block-list:is(.is-style-divided, .is-style-download) {
    32        list-style: none;
    43        padding-inline-start: 0;
    54}
    6 .wp-block-list.is-style-divided > li {
     5.wp-block-list:is(.is-style-divided, .is-style-download) > li {
    76        padding-block: var(--wp--preset--spacing--s);
    87        border-bottom: 0.0625rem solid var(--wp--preset--color--stroke);
    98}
    10 .wp-block-list.is-style-divided > li:first-child {
     9.wp-block-list:is(.is-style-divided, .is-style-download) > li:first-child {
    1110        border-top: 0.0625rem solid var(--wp--preset--color--stroke);
    1211}
     12.wp-block-list.is-style-download > li {
     13        position: relative;
     14        padding-inline-start: 2em;
     15}
     16.wp-block-list.is-style-download > li::before {
     17        content: "" / "";
     18        position: absolute;
     19        inset-block-start: calc(var(--wp--preset--spacing--s) + 0.1em);
     20        inset-inline-start: 0;
     21        width: 1.25em;
     22        height: 1.25em;
     23        background: var(--wp--preset--color--accent);
     24        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.75' stroke-linejoin='round'%3E%3Cpath d='M14 3H6v18h12V7zm0 0v4h4M12 10v7m-3-3 3 3 3-3'/%3E%3C/svg%3E") center / contain no-repeat;
     25}
     26.wp-block-list.is-style-download > li > a:first-child {
     27        display: block;
     28        width: fit-content;
     29        font-weight: 600;
     30}
    1331
    14 /*
    15  * Checklist: a decorative check mark before each item instead of the bullet. The row variant lets short facts
    16  * flow side by side and wrap, for trust strips. The mark is hidden from assistive technology.
    17  */
    1832.wp-block-list:is(.is-style-checklist, .is-style-checklist-row) {
    1933        list-style: none;
    … …  
    3549        font-weight: 600;
    3650}
    37 /* Accent marks fall below 3:1 on ink and accent bands, so they take the band text color there. */
    3851:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) .wp-block-list > li::before {
    3952        color: inherit;
     53}
     54:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) .is-style-download > li::before {
     55        background: currentcolor;
    4056}
    4157.wp-block-list.is-style-checklist-row {
    … …  
    4561}
    4662
    47 /*
    48  * Link columns in a footer navigation read as a register: no markers, dense rows, underline only on hover and focus.
    49  * A list of links under a heading in a nav is not running text, so 1.4.1 asks no underline there.
    50  */
    5163footer nav .wp-block-list:not(.is-style-divided, .is-style-checklist) {
    5264        display: grid;
  • leitvia/1.2.11/assets/css/blocks/core--navigation.css

    r355111 r356188  
    66        outline: 2px solid var(--wp--preset--color--focus);
    77        outline-offset: 2px;
    8         /* Inner ring for the double focus indicator, see core--button.css. */
    9         box-shadow: 0 0 0 2px var(--wp--preset--color--surface);
     8                box-shadow: 0 0 0 2px var(--wp--preset--color--surface);
    109}
    1110.wp-block-navigation .current-menu-item > a,
    … …  
    1615        text-underline-offset: 0.4em;
    1716}
    18 /* Navigation is a link-only context: no underline at rest, a fine one on hover. */
    1917.wp-block-navigation .wp-block-navigation-item__content:hover {
    2018        text-decoration: underline;
    … …  
    2321}
    2422
    25 /*
    26  * Submenu panel on desktop: a card below its toggle. `:not(.is-menu-open *)` leaves the overlay to core,
    27  * which lays submenus out inline. Sizes apply only while open, so a closed panel adds no scroll overflow.
    28  */
    2923.wp-block-navigation .has-child > .wp-block-navigation__submenu-container:not(.is-menu-open *) {
    3024        margin-top: var(--wp--preset--spacing--xs);
    … …  
    3832        padding: var(--wp--preset--spacing--s);
    3933}
    40 /* From six entries on the panel turns into a two-column grid. */
    4134.wp-block-navigation .has-child > .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container:has(> :nth-child(6)):not(.is-menu-open *) {
    4235        display: grid;
    … …  
    6962        line-height: 1.4;
    7063}
    71 /* Core flips the chevron when open; animate that only for people who did not ask for less motion. */
    7264@media (prefers-reduced-motion: no-preference) {
    7365        .wp-block-navigation .wp-block-navigation__submenu-icon svg {
    … …  
    8173}
    8274
    83 /*
    84  * Overlay menu: a centred column in the middle of the screen, whatever the desktop alignment.
    85  * The close button sits at the top right of that column, so it stays next to the menu instead of
    86  * in the far corner (short pointer path, WCAG 2.5.8 spirit). Auto margins centre the column
    87  * vertically but let a long menu scroll from its top, unlike justify-content: center.
    88  */
    8975.wp-block-navigation__responsive-container.is-menu-open {
    9076        display: flex;
    … …  
    117103        font-size: var(--wp--preset--font-size--heading-m);
    118104}
    119 /*
    120  * Submenus in the overlay: centred groups in a smaller size below their parent.
    121  * Core keeps every submenu open in the overlay and its toggle at aria-expanded="true", so the toggle does nothing;
    122  * it stays visible because it carries the parent label. Leitvia Studio makes the groups collapsible for long or
    123  * nested navigations (data-leitvia-collapsible). See docs/accessibility/known-limitations.md.
    124  */
    125105.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item {
    126106        font-size: var(--wp--preset--font-size--heading-s);
    … …  
    129109        padding: var(--wp--preset--spacing--xs) 0 0;
    130110}
    131 /* Overlay part (parts/navigation-overlay.html): close button, submenu toggles next to their labels. */
    132111.wp-block-navigation-overlay-close {
    133112        min-width: 2.75rem;
  • leitvia/1.2.11/assets/css/blocks/core--page-list.css

    r355111 r356188  
    1 /* Documentation menu: a quiet page tree without bullets, child pages indented. */
    21.page-template-page-docs .wp-block-page-list {
    32        list-style: none;
  • leitvia/1.2.11/assets/css/blocks/core--paragraph.css

    r355111 r356188  
    33}
    44
    5 /* Inline code in running text. The tint follows the text color, so it also reads on surface-alt, ink and accent sections. */
    65:where(p) code {
    76        padding: 0.1em 0.3em;
    … …  
    1211}
    1312
    14 /*
    15  * One small-text voice for badge, eyebrow and the column heads of footers: the ui font in caps, hierarchy through
    16  * color and space instead of weight. 12 px only for these caps labels, never for running text or links.
    17  */
    1813:is(.is-style-badge, .is-style-eyebrow) {
    1914        font-family: var(--wp--preset--font-family--ui);
    … …  
    2924}
    3025
    31 /* Accent text falls below 4.5:1 on ink and accent sections, so the eyebrow takes the section text color there. */
    3226:is(.has-background.has-ink-background-color, .has-background.has-accent-background-color, .is-style-inverse) .is-style-eyebrow {
    3327        color: inherit;
    3428}
    3529
    36 /*
    37  * Badge: the paragraph keeps its full width, so constrained layouts still line it up with the text column.
    38  * A single fit-content grid track shrinks to the label and the square tint is painted behind it by ::before,
    39  * absolutely positioned against that grid area so it stays out of auto placement.
    40  * Scoped to p, because post terms use the same style name with one pill per term, see core--post-terms.css.
    41  */
    4230p.is-style-badge {
    4331        display: grid;
  • leitvia/1.2.11/assets/css/blocks/core--post-comments-form.css

    r355111 r356188  
    1 /* Same double focus ring as buttons and links (see core--button.css) instead of the browser default. */
    21.wp-block-post-comments-form :is(input:not([type="submit"]), textarea):focus-visible {
    32        outline: 2px solid var(--wp--preset--color--focus);
  • leitvia/1.2.11/assets/css/blocks/core--post-content.css

    r355111 r356188  
    1 /*
    2  * Landing pages: full-width sections that follow each other touch, so colour bands meet without a strip of page background.
    3  * Every other block keeps the normal block gap. A full-width last section also meets the footer.
    4  */
    51.page-template-page-landing .wp-block-post-content > .alignfull + .alignfull {
    62        margin-block-start: 0;
    … …  
    106}
    117
    12 /*
    13  * Pages in easy language (template page-easy-language): the template sets the lead font size, the narrower reading
    14  * width and the larger gap between blocks. Text stays left aligned, whatever alignment a block sets, and words are
    15  * never hyphenated, so every word is read whole.
    16  */
    178.wp-block-post-content.is-easy-language {
    189        line-height: 1.6;
    … …  
    2011        hyphens: manual;
    2112}
     13.wp-block-post-content.is-easy-language .wp-block-heading {
     14        hyphens: manual;
     15}
    2216.wp-block-post-content.is-easy-language :is(.has-text-align-center, .has-text-align-right, .has-text-align-justify) {
    2317        text-align: start;
    2418}
     19
     20.page-template-page-docs .wp-block-post-content > .alignfull {
     21        padding-inline: 0;
     22}
     23.page-template-page-docs .wp-block-post-content > .alignfull:is(.has-background, .is-style-inverse) {
     24        padding-inline: var(--wp--preset--spacing--m);
     25}
  • leitvia/1.2.11/assets/css/blocks/core--post-template.css

    r355111 r356188  
    1 /* Cards answer hover with a fine underline on the title, never by scaling the image. */
    21.wp-block-post-template .wp-block-post-title a {
    32        text-decoration: none;
  • leitvia/1.2.11/assets/css/blocks/core--post-terms.css

    r355111 r356188  
    66}
    77
    8 /* Badge: one pill per term, same label type as the paragraph badge. */
    98.wp-block-post-terms.is-style-badge {
    109        display: flex;
  • leitvia/1.2.11/assets/css/blocks/core--post-title.css

    r355111 r356188  
    1 /*
    2  * Titles fill the line and only avoid a lone last word. Balanced wrapping halved two-line titles in the journal
    3  * list and on posts, so they broke at half the column width.
    4  */
    51.wp-block-post-title {
    62        text-wrap: pretty;
     3        overflow-wrap: break-word;
     4}
     5:lang(de) .wp-block-post-title {
     6        hyphens: auto;
    77}
    88.wp-block-post-title a:hover {
  • leitvia/1.2.11/assets/css/blocks/core--quote.css

    r355111 r356188  
    1 /* Drop the browser's side indent so quotes line up with the text around them. */
    21:where(.wp-block-quote) {
    32        margin-inline: 0;
    43}
    54
    6 /* On a colored or inverse section or quote, the citation takes the text color so it keeps its contrast. */
    75:where(.has-text-color, .is-style-inverse) .wp-block-quote cite,
    86.wp-block-quote.has-text-color cite {
  • leitvia/1.2.11/assets/css/blocks/core--search.css

    r355111 r356188  
    1 /* Same double focus ring as buttons and links (see core--button.css) instead of the browser default. */
    21.wp-block-search__input:focus-visible {
    32        outline: 2px solid var(--wp--preset--color--focus);
    … …  
    54        box-shadow: 0 0 0 2px var(--wp--preset--color--surface);
    65}
    7 /*
    8  * In a flex row (header-search) the form would keep the intrinsic width of its input and overflow at 320px.
    9  * Without the minimum it shrinks to the row and the input takes what is left next to the button.
    10  */
    116.wp-block-search {
    127        min-width: 0;
    138}
    14 /* Field and button share one 48 px height and the small radius. */
    159.wp-block-search__input {
    1610        min-height: 3rem;
    … …  
    1812        font-family: var(--wp--preset--font-family--ui);
    1913}
     14body:has(main .wp-block-post-content .wp-block-search) header .wp-block-search {
     15        display: none;
     16}
  • leitvia/1.2.11/assets/css/blocks/core--shortcode.css

    r355111 r356188  
    1 /* WooCommerce's account forms come in through the shortcode block. Its "Show password" toggle is 22 by 22 px, below
    2    the 24 px minimum target (WCAG 2.5.8); at least 1.5rem in both directions. */
    31.woocommerce form .show-password-input,
    42.woocommerce-page form .show-password-input {
  • leitvia/1.2.11/assets/css/blocks/core--table.css

    r355111 r356188  
    1 /*
    2  * Comparison: hairlines between rows, meta caps in the head, tabular figures. Columns after the first align to the
    3  * end so figures line up. Rows cannot carry classes, so the highlighted row is the table footer (core "Footer section").
    4  * Columns size to their content even with fixed layout on, so words never break mid-word. Tables wider than the
    5  * screen scroll inside the figure, which functions.php makes a focusable region so arrow keys scroll it.
    6  */
    71.wp-block-table.is-style-comparison {
    82        overflow-x: auto;
    … …  
    2317        word-break: normal;
    2418}
    25 /* Low specificity, so the column alignment set in the editor still wins. */
    2619:where(.wp-block-table.is-style-comparison) :is(th, td) {
    2720        text-align: start;
    … …  
    3023        text-align: end;
    3124}
    32 /* Keep figures and their units on one line. */
    3325.wp-block-table.is-style-comparison tbody td:not(:first-child) {
    3426        white-space: nowrap;
    3527}
    3628.wp-block-table.is-style-comparison :is(th, td):first-child {
     29        position: sticky;
     30        inset-inline-start: 0;
     31        z-index: 1;
    3732        min-width: 6em;
    3833        padding-inline-start: 0;
     34        background-color: var(--wp--preset--color--surface);
     35}
     36:is(.has-background:not(.has-surface-background-color), .is-style-inverse) .wp-block-table.is-style-comparison :is(th, td):first-child {
     37        position: static;
     38        background-color: transparent;
    3939}
    4040.wp-block-table.is-style-comparison :is(th, td):last-child {
    … …  
    5858        outline: 0.125rem solid var(--wp--preset--color--focus);
    5959        outline-offset: 0.125rem;
    60         /* Inner ring for the double focus indicator, see core--button.css. */
    61         box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
     60                box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
    6261}
  • leitvia/1.2.11/assets/css/blocks/core--tabs.css

    r355111 r356188  
    1 /* Core tabs in the roles of the theme: a stroke under the tab list, the selected tab marked in accent. */
    21.wp-block-tab-list {
    32        gap: 0;
    … …  
    1918        outline: 0.125rem solid var(--wp--preset--color--focus);
    2019        outline-offset: 0.125rem;
    21         /* Inner ring for the double focus indicator, see core--button.css. */
    22         box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
     20                box-shadow: 0 0 0 0.125rem var(--wp--preset--color--surface);
    2321}
    2422.wp-block-tab-panel {
    2523        padding-block: var(--wp--preset--spacing--s);
    2624}
    27 /* Tab label above each panel, only rendered without scripting by Leitvia Studio. */
    2825.wp-block-tab-panel__label {
    2926        margin-block-start: 0;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--account.css

    r355111 r356188  
    1 /* Account: login and registration side by side from 782 px, 48 px fields and buttons in the ui font, square frames;
    2    signed in, a vertical list on the left and the content on the right. WooCommerce's rules reach 0,3,1. */
    31body.woocommerce-account .woocommerce {
    42        font-family: var(--wp--preset--font-family--ui);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--add-to-cart-form.css

    r355111 r356188  
    1 /* Classic add to cart form: quantity, variation selects and button share 48 px, the ui font and the field
    2    look (ink-muted frame, 4.5:1 in every palette). Disabled stays readable instead of half opacity. WooCommerce: 0,3,1. */
    31body .wp-block-add-to-cart-form {
    42        & form.cart:not(.variations_form),
    … …  
    2826        & .reset_variations {
    2927                margin-inline-start: var(--wp--preset--spacing--s);
     28                padding: 0;
     29                border: 0;
     30                background: none;
    3031                color: var(--wp--preset--color--ink);
     32                font: inherit;
     33                text-decoration: underline;
     34                cursor: pointer;
    3135        }
    3236        & .single_add_to_cart_button.button {
  • leitvia/1.2.11/assets/css/blocks/woocommerce--cart.css

    r355111 r356188  
    1 /* Cart. Quantity frame in ink-muted (WooCommerce: 1.5:1). WooCommerce reaches 0,4,0. */
    21body .wc-block-cart.wc-block-cart {
    32        & .wc-block-components-quantity-selector {
    … …  
    4645                border-radius: var(--wp--preset--border-radius--s);
    4746        }
    48         /* The fixed 132 px column overflows at 320 px. */
    49         & .wc-block-cart-items__row {
     47                & .wc-block-cart-items__row {
    5048                grid-template-columns: 5rem minmax(0, 1fr);
    5149        }
    5250}
    5351
    54 /* Germanized notes: grey 4.19:1, ink-muted 4.5:1 */
    5552body :is(.wc-block-components-product-details [class*="__gzd-"] .wc-block-components-product-details__value, .wc-gzd-unit-price, .wc-gzd-small-business-info) {
    5653        color: var(--wp--preset--color--ink-muted);
    5754}
    5855
    59 /* Focus clear of the pinned checkout button (2.4.11) */
    6056html:has(.wc-block-cart__submit-container--sticky) {
    6157        scroll-padding-bottom: 6rem;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--catalog-sorting.css

    r355111 r356188  
    1 /* Sorting in the ui font and the field look instead of the system select. */
    21body .woocommerce-ordering select {
    32        min-height: 2.75rem;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--checkout.css

    r355111 r356188  
    1 /* Checkout: form left, summary on surface-alt right, 48 px fields, ink-muted frames (4.5:1), 52 px button. WC 0,4,0 */
    21body .wc-block-checkout.wc-block-checkout {
    32        & :is(.wc-block-components-text-input input, .wc-blocks-components-select__container, .wc-blocks-components-select__select, .wc-block-components-textarea, .wc-block-components-checkbox__input[type="checkbox"], .wc-block-components-radio-control__input) {
    … …  
    4645                border: 0;
    4746        }
    48         /* Germanized: products on surface, not its fixed grey */
    49         &.wc-gzd-checkout .wc-block-components-order-summary {
     47                &.wc-gzd-checkout .wc-block-components-order-summary {
    5048                background-color: var(--wp--preset--color--surface);
    5149        }
    52         /* Small screens: a tinted summary bar on top */
    53         & .wc-block-components-checkout-order-summary__title {
     50                & .wc-block-components-checkout-order-summary__title {
    5451                padding-inline: var(--wp--preset--spacing--s);
    5552                background-color: var(--wp--preset--color--surface-alt);
    … …  
    6259                font-variant-numeric: tabular-nums lining-nums;
    6360        }
    64         /* Summary product names (h3) keep the ui font */
    65         & .wc-block-components-order-summary-item .wc-block-components-product-name {
     61                & .wc-block-components-order-summary-item .wc-block-components-product-name {
    6662                font-family: inherit;
    6763                font-weight: 500;
    … …  
    8278}
    8379
    84 /* Germanized notes: grey 4.19:1, ink-muted 4.5:1 */
    8580body :is(.wc-block-components-product-details [class*="__gzd-"] .wc-block-components-product-details__value, .wc-gzd-unit-price, .wc-gzd-small-business-info) {
    8681        color: var(--wp--preset--color--ink-muted);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--customer-account.css

    r355111 r356188  
    1 /* Account link in the shop header: a 44 px target around the icon, like the mini cart button. */
    21.wp-block-woocommerce-customer-account a {
    32        display: inline-flex;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--mini-cart.css

    r355111 r356188  
    1 /* The closed drawer stays in the page, hidden only from assistive technology; hidden for everyone, Tab skips it
    2    (WCAG 2.4.3, 4.1.2). Open: surface and ink, two full-width buttons. */
    31.wc-block-mini-cart__drawer[aria-hidden="true"] {
    42        visibility: hidden;
    … …  
    3836        }
    3937}
    40 /* Header button: a 44 px target, the count in ink. */
    4138.wc-block-mini-cart__button {
    4239        min-width: 2.75rem;
    … …  
    5451}
    5552
    56 /* Germanized notes: grey 4.19:1, ink-muted 4.5:1 */
    5753body :is(.wc-block-components-product-details [class*="__gzd-"] .wc-block-components-product-details__value, .wc-gzd-unit-price, .wc-gzd-small-business-info, .wc-gzd-block-mini-cart-notices__notice) {
    5854        color: var(--wp--preset--color--ink-muted);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-button.css

    r355111 r356188  
    1 /* Product cards (collection, related products): image, title, price and button on one left edge; the title ink in the
    2    reading size, the button an outline across the column. */
    31:is(.wc-block-product, .wp-block-post.product) {
    42        --wp--preset--font-size--heading-s: 1.125rem;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-details.css

    r355111 r356188  
    1 /* Classic product tabs as a quiet row of ui labels over a hairline, the active one underlined in ink; attributes and
    2    review form in the theme's table and field look instead of WooCommerce's boxes (its rules reach 0,4,2). */
    31html body .wp-block-woocommerce-product-details.wp-block-woocommerce-product-details {
    42        & ul.tabs.wc-tabs {
    … …  
    4038        }
    4139        & .woocommerce-product-attributes :is(th, td) {
    42                 padding: var(--wp--preset--spacing--xs) var(--wp--preset--spacing--s) var(--wp--preset--spacing--xs) 0;
     40                padding-block: var(--wp--preset--spacing--xs);
     41                padding-inline: 0 var(--wp--preset--spacing--s);
    4342                border: 0;
    4443                border-bottom: 1px solid var(--wp--preset--color--stroke);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-filters.css

    r355111 r356188  
    1 /* Shop focus ring, on the thumb for the price slider (WooCommerce forces outline: none on its inputs). The closed
    2    mobile overlay sits off screen: hidden, so Tab skips it. */
    31body .wp-block-woocommerce-product-filters :is(a, button, input, [tabindex]):focus-visible {
    42        outline: 2px solid var(--wp--preset--color--focus);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-gallery-large-image.css

    r355111 r356188  
    1 /* Image viewer: focus ring; no zoom transition with reduced motion. */
    21.wc-block-product-gallery-large-image__container:focus-visible {
    32        outline: 2px solid var(--wp--preset--color--focus);
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-image.css

    r355111 r356188  
    1 /* A tint where a product has no image. Sale badge: a small square label at the top left, also in the classic loop
    2    (WooCommerce's olive circle has 3.4:1). */
    31.wc-block-components-product-image {
    42        background-color: var(--wp--preset--color--surface-alt);
    … …  
    75html body .woocommerce ul.products li.product .onsale {
    86        position: absolute;
    9         inset: 0.75rem auto auto 0.75rem;
     7        inset-block: 0.75rem auto;
     8        inset-inline: 0.75rem auto;
    109        z-index: 1;
    1110        min-width: 0;
  • leitvia/1.2.11/assets/css/blocks/woocommerce--product-price.css

    r355111 r356188  
    1 /* Prices in the ui font with tabular figures. The struck regular price stays readable in ink-muted (4.5:1 in every
    2    palette), also in the upsells from WooCommerce's classic loop (its half-transparent one has 3.4:1). */
    31body .wc-block-components-product-price,
    42html body .woocommerce ul.products li.product .price {
  • leitvia/1.2.11/assets/css/blocks/woocommerce--store-notices.css

    r355111 r356188  
    1 /* Shop notices in the notice look of core--group.css: role tint, hairline frame, ink text, icon on the role color.
    2    Every shop template has it. */
    31.wc-block-components-notice-banner.wc-block-components-notice-banner {
    42        --leitvia-notice: var(--wp--preset--color--ink-muted);
    … …  
    2220        fill: var(--wp--preset--color--surface);
    2321}
    24 /* Double focus ring of core--button.css on every shop control; 0,4,1 beats WooCommerce's 0,4,0. */
    2522body :is(.wc-block-components-notice-banner.wc-block-components-notice-banner, .wc-block-checkout, .wc-block-cart, .wp-block-add-to-cart-form, .wp-block-woocommerce-product-details, .woocommerce-ordering, .wp-block-woocommerce-customer-account) :is(a, button, input, select, textarea, [tabindex]):focus-visible {
    2623        outline: 2px solid var(--wp--preset--color--focus);
  • leitvia/1.2.11/design.md

    r355111 r356188  
    9090| `content-statement` | accent, asymmetric, airy | One sentence in `display` size on the accent color |
    9191| `teaser-editorial-grid` | surface, grid, regular | Lead story on two thirds, four more posts beside it |
     92| `teaser-front-page` | surface, asymmetric, dense | Newspaper front: the sticky lead wide, headlines in brief and three more stories beside it |
    9293| `content-media-pair` | surface-alt, asymmetric, airy | Two images of different size, offset, with captions |
     94| `hero-overlap` | surface, overlap, regular | Opening photo on two thirds, the card with the h1 reaching into it from the right |
     95| `hero-teaser-trio` | surface, grid, regular | Opening with three tall picture teasers instead of one message |
    9396
    9497Offsets and overlaps come only from spacing presets (a top margin of `xxl`, or a negative top margin of `xl` written as `calc(var(--wp--preset--spacing--xl) * -1)`), never from fixed values. Keep the DOM order the reading order: the text comes first, the image follows.
    9598
    96 Leitvia Studio adds patterns with its own blocks (bento grid, reveal, highlight format, pricing, comparison table, feature group). The contract lists them under `studioPatterns` with the same metadata; their slugs start with `leitvia-studio/`. Use them only when Leitvia Studio is active. The theme's own patterns never contain Studio blocks, so the theme stays complete without the plugin. Starting patterns of Studio for a template part area are not listed: `leitvia-studio/header-announcement` puts the announcement bar as a band over the full width above `leitvia/header-default`; pick it for the header in the Site Editor.
    97 
    98 Shop patterns (`leitvia/shop-*`, inserter category Shop) carry `requires: [ "woocommerce" ]` and exist only while WooCommerce runs: product hero, benefits bar, category tiles, new arrivals, bestsellers and trust badges. A shop home page on `page-landing` reads well as `leitvia/shop-product-hero` > `leitvia/shop-usp-bar` > `leitvia/shop-category-tiles` > `leitvia/shop-new-arrivals` > `leitvia/shop-bestsellers` > `leitvia/proof-trust-strip`. `leitvia/shop-legal-info` (tax and shipping note, unit price, delivery time) also needs Germanized; the single product template already shows it below the price. Name payment methods as text, never as logos of other brands.
     99Leitvia Studio adds patterns with its own blocks (bento grid, reveal, highlight format, pricing, comparison table, feature group). The contract lists them under `studioPatterns` with the same metadata; their slugs start with `leitvia-studio/`. Use them only when Leitvia Studio is active. The theme's own patterns never contain Studio blocks, so the theme stays complete without the plugin. Starting patterns of Studio for a template part area are not listed: `leitvia-studio/header-announcement` puts the announcement bar as a band over the full width above `leitvia/header-default`; pick it for the header in the Site Editor. For a news site, `leitvia/header-masthead` sets a wide logo centered above the navigation like the masthead of a daily, and `leitvia-studio/content-timeline` tells the background of a story as dated entries.
     100
     101Shop patterns (`leitvia/shop-*`, inserter category Shop) carry `requires: [ "woocommerce" ]` and exist only while WooCommerce runs: product hero, benefits bar, category tiles, new arrivals, bestsellers and trust badges. A shop home page on `page-landing` reads well as `leitvia/shop-product-hero` > `leitvia/shop-usp-bar` > `leitvia/shop-category-tiles` > `leitvia/shop-new-arrivals` > `leitvia/shop-bestsellers` > `leitvia/proof-trust-strip`. `leitvia/shop-legal-info` (tax and shipping note, unit price, delivery time) also needs Germanized; the single product template already shows it below the price. `leitvia/shop-legal-guarantee` holds the EU notice on the legal guarantee from Germanized (block `woocommerce-germanized/product-legal-guarantee`) and sits below the add to cart form; it shows only while the notice is switched on in Germanized. The theme renders that notice everywhere Germanized prints it (product, cart, checkout, shortcode, footer) as a details block with a text summary, the label image and a link to europa.eu, and moves Germanized's footer location inside the footer landmark. Name payment methods as text, never as logos of other brands.
    99102
    100103### Example: home page
    … …  
    136139| Page type | Template | Typical patterns |
    137140| --- | --- | --- |
    138 | Home | `page-landing` | Hero (split image or centered), `proof-logos` or `proof-trust-strip`, `teaser-services`, a proof pattern, `teaser-posts-grid` or `teaser-posts-list`, `cta-banner` |
     141| Home | `page-landing` | Hero (split image, centered, overlap or three teasers), `proof-logos` or `proof-trust-strip`, `teaser-services`, a proof pattern, `teaser-posts-grid` or `teaser-posts-list`, `cta-banner` |
    139142| Service | `page-landing` | `hero-centered` or `hero-split-image`, `content-text-media`, `content-steps`, `content-feature-grid`, `proof-testimonials-grid` or `content-quote`, `offer-pricing-3` or `content-price-list`, `content-faq`, `cta-contact` |
    140 | Product | `page-landing` | `content-feature-catalog`, `content-compare-two`, `offer-pricing-3`, `content-changelog`, `teaser-posts-badge` |
     143| Product | `page-landing` | `content-feature-catalog`, `content-compare-two`, `offer-pricing-3`, `content-changelog`, `content-downloads`, `teaser-posts-badge` |
     144| Blog | `home`, `archive`, `author`, `single` | No patterns of your own: the templates carry the overview with continue reading links and pagination, category and author archives with their descriptions, and the post page with author box, previous and next post and related posts. A posts page set in the reading settings gives the overview its h1 |
    141145| Article | `single` | Core blocks in reading width; `content-quote`, `content-stats` or `content-steps` inside long reads; `cta-newsletter` at the end |
    142146| About | `page-landing` | `hero-editorial`, `content-two-columns`, `content-stats`, `proof-team`, `content-quote`, `cta-contact` |
    143147| Contact | `page` | `cta-contact`, `content-faq`, a form plugin block in a plain section |
     148| Documentation home | `page-landing` | `hero-search`, `content-feature-grid` or `content-steps`, `content-changelog`, `content-downloads`, `content-faq`, `cta-contact` |
    144149
    145150Before using a pattern read its `useWhen` and `docs.avoidWhen`. Respect `docs.contentLength` (characters of the main heading and of each supporting text) so layouts do not break. `images` lists every image slot with aspect ratio, display width and the pixel size to deliver.
    … …  
    173178- Every Search block is a search landmark named after its label. Give each search on a page its own label: the theme uses Site search (header), Search products (shop header), Search documentation (documentation sidebar) and Search this site (404). Searches in templates keep the default name Search.
    174179- On sites with more than a few pages use `header-search`, so every page can be found by search as well as by navigation (WCAG 2.4.5).
     180- Files to download sit in a list, one text link per file that names the file, its format and its size ("Price list 2026 (PDF, 180 KB)"), as in `content-downloads` with the Download list style. Never an icon as the only link; the file mark of the style is decorative.
    175181- Tables keep their caption; wide tables and terminal code become focusable scroll regions automatically.
    176182- Pages in easy language (Leichte Sprache) are normal pages on the template `page-easy-language`; the template sets size, width and spacing. Write them by the rules of easy language: short sentences, one thought per sentence, common words, explain every unavoidable term, active voice, no abbreviations, numbers as digits. Headings and lists help more than long paragraphs. Leitvia Studio links the page and its original (setting in the page sidebar, block "Easy language switch").
    … …  
    180186## Template parts
    181187
     188Pick the header by what visitors need first: `header-default` for most sites, `header-cta` when one action such as booking matters on every page, `header-utility` when opening hours and a phone number belong on every page, `header-split` when the logo should lead in the middle, `header-centered` or `header-masthead` for publications. The button of `header-cta`, `header-utility` and `header-split` (block style Header action) is hidden below 1024 px, so its target must also be in the navigation.
     189
    182190Every header pattern opens the template part `navigation-overlay` as its mobile menu: a close button and the navigation as a vertical list on the `surface` background. Edit it in the Site Editor like header and footer. Its navigation shows the site's menu by default; when the header navigation is set to a specific menu, set the same menu in the overlay. The copyright line of every footer pattern is bound to the source `leitvia/site-meta` (key `copyright`) and always shows the current year, also after the footer is saved in the Site Editor. Keep the binding instead of typing a year.
    183191
  • leitvia/1.2.11/functions.php

    r355111 r356188  
    6262
    6363        $styles = array(
     64                'core/columns'    => array(
     65                        'overlap' => __( 'Overlap', 'leitvia' ),
     66                ),
     67                'core/buttons'    => array(
     68                        'header-action' => __( 'Header action', 'leitvia' ),
     69                ),
    6470                'core/paragraph'  => array(
    6571                        'badge'   => __( 'Badge', 'leitvia' ),
    … …  
    6773                ),
    6874                'core/group'      => array(
    69                         'note'    => __( 'Note', 'leitvia' ),
    70                         'success' => __( 'Success', 'leitvia' ),
    71                         'warning' => __( 'Warning', 'leitvia' ),
    72                         'inverse' => __( 'Inverse', 'leitvia' ),
     75                        'note'         => __( 'Note', 'leitvia' ),
     76                        'success'      => __( 'Success', 'leitvia' ),
     77                        'warning'      => __( 'Warning', 'leitvia' ),
     78                        'inverse'      => __( 'Inverse', 'leitvia' ),
     79                        'header-split' => __( 'Header split', 'leitvia' ),
    7380                ),
    7481                'core/cover'      => array(
    … …  
    8592                        'checklist'     => __( 'Checklist', 'leitvia' ),
    8693                        'checklist-row' => __( 'Checklist row', 'leitvia' ),
     94                        'download'      => __( 'Download', 'leitvia' ),
    8795                ),
    8896                'core/post-terms' => array(
    … …  
    155163
    156164/**
     165 * Block bindings source leitvia/term-image: the url of an image block inside a term template becomes the image of the
     166 * term (term meta thumbnail_id, as WooCommerce stores the image of a product category). Without an image the block
     167 * keeps no src and core drops it, so the tile shows name and description only.
     168 */
     169function register_term_image_binding(): void {
     170        register_block_bindings_source(
     171                'leitvia/term-image',
     172                array(
     173                        'label'              => __( 'Term image', 'leitvia' ),
     174                        'get_value_callback' => __NAMESPACE__ . '\term_image_value',
     175                        'uses_context'       => array( 'termId' ),
     176                )
     177        );
     178}
     179add_action( 'init', __NAMESPACE__ . '\register_term_image_binding' );
     180
     181/**
     182 * URL of the term image in the size of the block, null without a term or an image.
     183 *
     184 * @param array     $args      Binding arguments, unused.
     185 * @param \WP_Block $block     Image block.
     186 * @param string    $attribute Bound attribute.
     187 */
     188function term_image_value( array $args, \WP_Block $block, string $attribute ): ?string {
     189        $image = 'url' === $attribute ? (int) get_term_meta( (int) ( $block->context['termId'] ?? 0 ), 'thumbnail_id', true ) : 0;
     190        $url   = $image ? wp_get_attachment_image_url( $image, (string) ( $block->attributes['sizeSlug'] ?? 'large' ) ) : false;
     191        return $url ? $url : null;
     192}
     193
     194/**
     195 * Width and height for an image bound to leitvia/term-image, from the attachment in the size of the block (CLS).
     196 *
     197 * @param string    $html     Block HTML.
     198 * @param array     $block    Parsed block.
     199 * @param \WP_Block $instance Block instance with the term context.
     200 */
     201function term_image_size( string $html, array $block, \WP_Block $instance ): string {
     202        if ( 'leitvia/term-image' !== ( $block['attrs']['metadata']['bindings']['url']['source'] ?? '' ) ) {
     203                return $html;
     204        }
     205        $image = (int) get_term_meta( (int) ( $instance->context['termId'] ?? 0 ), 'thumbnail_id', true );
     206        $size  = $image ? wp_get_attachment_image_src( $image, (string) ( $block['attrs']['sizeSlug'] ?? 'large' ) ) : false;
     207        $tags  = new \WP_HTML_Tag_Processor( $html );
     208        if ( $size && $tags->next_tag( 'img' ) && null === $tags->get_attribute( 'width' ) ) {
     209                $tags->set_attribute( 'width', (string) $size[1] );
     210                $tags->set_attribute( 'height', (string) $size[2] );
     211        }
     212        return $tags->get_updated_html();
     213}
     214add_filter( 'render_block_core/image', __NAMESPACE__ . '\term_image_size', 10, 3 );
     215
     216/**
    157217 * Returns the text of the first figcaption in a block's HTML, or an empty string.
    158218 *
    … …  
    249309
    250310/**
     311 * Namespace of the related posts query below a single post, see patterns/hidden-page-related-posts.php.
     312 */
     313const RELATED_POSTS = 'leitvia/related-posts';
     314
     315/**
     316 * The related posts query takes the categories of the current post; core leaves the post itself out (excludeCurrent).
     317 * Without categories it lists the latest other posts.
     318 *
     319 * @param array $block Parsed block.
     320 */
     321function related_posts_query( array $block ): array {
     322        if ( 'core/query' !== $block['blockName'] || RELATED_POSTS !== ( $block['attrs']['namespace'] ?? '' ) || ! is_array( $block['attrs']['query'] ?? null ) ) {
     323                return $block;
     324        }
     325        $categories = array_map( 'intval', wp_get_post_categories( (int) get_the_ID() ) );
     326        if ( $categories ) {
     327                $block['attrs']['query']['taxQuery'] = array( 'category' => $categories );
     328        }
     329        return $block;
     330}
     331add_filter( 'render_block_data', __NAMESPACE__ . '\related_posts_query' );
     332
     333/**
     334 * Start-aligned content in right-to-left languages. Templates and patterns align their constrained content to the
     335 * start edge ("justifyContent":"left", contract layout), and core writes that as a physical margin-left: 0 !important
     336 * on the children, so in RTL the column would stay on the left. On an RTL site the theme reads "left" as the start
     337 * edge and hands core "right". Flex layouts already justify with flex-start and stay as they are.
     338 *
     339 * @param array $block Parsed block.
     340 */
     341function rtl_start_justification( array $block ): array {
     342        $layout = $block['attrs']['layout'] ?? null;
     343        if ( ! is_rtl() || ! is_array( $layout ) || 'constrained' !== ( $layout['type'] ?? '' ) || 'left' !== ( $layout['justifyContent'] ?? '' ) ) {
     344                return $block;
     345        }
     346        $block['attrs']['layout']['justifyContent'] = 'right';
     347        return $block;
     348}
     349add_filter( 'render_block_data', __NAMESPACE__ . '\rtl_start_justification' );
     350
     351/**
     352 * Drops the related posts with their heading while there is no other post to show.
     353 *
     354 * @param string $html  Block HTML.
     355 * @param array  $block Parsed block.
     356 */
     357function hide_empty_related_posts( string $html, array $block ): string {
     358        return RELATED_POSTS === ( $block['attrs']['namespace'] ?? '' ) && ! str_contains( $html, 'wp-block-post-template' ) ? '' : $html;
     359}
     360add_filter( 'render_block_core/query', __NAMESPACE__ . '\hide_empty_related_posts', 10, 2 );
     361
     362/**
    251363 * The documentation sidebar marks its page list with this class, see patterns/hidden-page-docs-sidebar.php.
    252364 */
    … …  
    327439        $base         = get_theme_file_uri( 'assets/images/' );
    328440        // Content saved with a path relative to the site root (/wp-content/themes/...) counts as well.
    329         $path = (string) wp_parse_url( $base, PHP_URL_PATH );
     441        $root = (string) wp_parse_url( $base, PHP_URL_PATH );
    330442        while ( $tags->next_tag( 'img' ) ) {
    331443                $src = (string) $tags->get_attribute( 'src' );
    332                 if ( null !== $tags->get_attribute( 'width' ) || ! ( str_starts_with( $src, $base ) || str_starts_with( $src, $path ) ) ) {
     444                if ( null !== $tags->get_attribute( 'width' ) || ! ( str_starts_with( $src, $base ) || str_starts_with( $src, $root ) ) ) {
    333445                        continue;
    334446                }
    … …  
    352464 * renders in its own font instead of swapping from the fallback (layout shift through font-display: swap).
    353465 * The files come from this site; style variations and token sets that change the fonts are resolved through the
    354  * global settings. Italic, Latin Extended and monospace files load on demand as before.
    355  */
    356 function preload_fonts(): void {
    357         $families = array();
     466 * global settings. Italic, Latin Extended and monospace files load on demand as before. Core prints the links
     467 * (filter wp_preload_resources, wp_head at priority 1).
     468 *
     469 * @param array<int, array<string, string>> $resources Resources core preloads.
     470 * @return array<int, array<string, string>>
     471 */
     472function preload_fonts( $resources ): array {
     473        $resources = (array) $resources;
     474        $families  = array();
    358475        foreach ( (array) wp_get_global_settings( array( 'typography', 'fontFamilies' ) ) as $origin ) {
    359476                foreach ( (array) $origin as $family ) {
    … …  
    386503        }
    387504        foreach ( array_unique( $urls ) as $url ) {
    388                 printf( '<link rel="preload" href="%s" as="font" type="font/woff2" crossorigin>' . "\n", esc_url( $url ) );
    389         }
    390 }
    391 add_action( 'wp_head', __NAMESPACE__ . '\preload_fonts', 1 );
     505                $resources[] = array(
     506                        'href'        => $url,
     507                        'as'          => 'font',
     508                        'type'        => 'font/woff2',
     509                        'crossorigin' => 'anonymous',
     510                );
     511        }
     512        return $resources;
     513}
     514add_filter( 'wp_preload_resources', __NAMESPACE__ . '\preload_fonts' );
    392515
    393516/**
    … …  
    448571}
    449572add_action( 'init', __NAMESPACE__ . '\register_shop_patterns', 20 );
     573
     574/**
     575 * "Clear" next to the options of a variable product resets the form: an action, so a button instead of WooCommerce's
     576 * link to "#" (WCAG 4.1.2, a link would announce a page change and Space would not press it). WooCommerce finds it by
     577 * the class reset_variations; woocommerce--add-to-cart-form.css draws it as a text link. Replaces the markup of the
     578 * filter woocommerce_reset_variations_link.
     579 */
     580function reset_variations_button(): string {
     581        return '<button type="button" class="reset_variations" aria-label="' . esc_attr__( 'Clear options', 'leitvia' ) . '">' . esc_html__( 'Clear', 'leitvia' ) . '</button>';
     582}
     583add_filter( 'woocommerce_reset_variations_link', __NAMESPACE__ . '\reset_variations_button' );
     584
     585/**
     586 * The EU notice on the legal guarantee from Germanized as a disclosure from core blocks. Germanized opens it in a popover
     587 * from a link to the image file, closes it with a link to "#" inside a tooltip, and its full variant is a poster of
     588 * 1,654 px. Here a details block with a text summary holds the official label (the image of Germanized, served from the
     589 * site) at 20rem and a text link to the notice on europa.eu: keyboard and screen readers get a native disclosure, no
     590 * script, no link without a target. The full variant starts open. The note Germanized adds in a mixed cart stays as text,
     591 * before the disclosure or, in the link variant, as part of its summary. Germanized prints this filter's result in the
     592 * product block, the cart and checkout blocks, the shortcode [gzd_legal_guarantee] and its global locations; without
     593 * Germanized the filter never runs. Styles come from core/details and core/image, the theme CSS stays as it is.
     594 * Presentation only: this and the two functions below change how and where the notice of Germanized shows; they add
     595 * no shop function, store nothing and decide nothing legal. The text, image and link come from Germanized.
     596 *
     597 * @param string $html    Markup from Germanized.
     598 * @param string $variant full, preview or link.
     599 * @param string $lang    Language of the label, empty for the language of the request.
     600 */
     601function legal_guarantee_notice( $html, $variant = '', $lang = '' ): string {
     602        if ( ! function_exists( 'wc_gzd_get_legal_guarantee_image_url' ) || ! function_exists( 'wc_gzd_get_legal_guarantee_url' ) ) {
     603                return (string) $html;
     604        }
     605        $html    = (string) $html;
     606        $summary = __( 'Your legal guarantee rights', 'leitvia' );
     607        $note    = preg_match( '#class="wc-gzd-legal-guarantee-mixed-cart-notice">(.*?)</p>#s', $html, $match ) ? wp_strip_all_tags( $match[1] ) : '';
     608        if ( 'link' === $variant && preg_match( '#class="wc-gzd-popover-trigger"[^>]*>(.*?)</a>#s', $html, $match ) && '' !== trim( wp_strip_all_tags( $match[1] ) ) ) {
     609                $summary = trim( wp_strip_all_tags( $match[1] ) );
     610        }
     611        // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Germanized's filter, so a shop's own alt text applies here too.
     612        $alt   = apply_filters( 'woocommerce_gzd_legal_guarantee_alt_text', __( 'Your legal guarantee rights: Minimum two-year legal guarantee protection for goods sold in the European Union.', 'leitvia' ), $variant, $lang, '' );
     613        $open  = 'full' === $variant;
     614        $block = sprintf(
     615                '<!-- wp:details {"showContent":%1$s} --><details class="wp-block-details"%2$s><summary>%3$s</summary>'
     616                . '<!-- wp:image {"width":"20rem","sizeSlug":"full"} --><figure class="wp-block-image size-full is-resized"><img src="%4$s" alt="%5$s" width="1654" height="2339" loading="lazy" decoding="async" style="width:20rem"/></figure><!-- /wp:image -->'
     617                . '<!-- wp:paragraph --><p><a href="%6$s">%7$s</a></p><!-- /wp:paragraph --></details><!-- /wp:details -->',
     618                $open ? 'true' : 'false',
     619                $open ? ' open' : '',
     620                esc_html( $summary ),
     621                esc_url( wc_gzd_get_legal_guarantee_image_url( $lang ) ),
     622                esc_attr( (string) $alt ),
     623                esc_url( wc_gzd_get_legal_guarantee_url( $lang ) ),
     624                esc_html__( 'The legal guarantee in the EU, explained on europa.eu', 'leitvia' )
     625        );
     626        $note  = ( '' !== $note && 'link' !== $variant ) ? '<p class="wc-gzd-legal-guarantee-mixed-cart-notice">' . esc_html( $note ) . '</p>' : '';
     627        return '<div class="wc-gzd-legal-guarantee-label leitvia-legal-guarantee">' . $note . do_blocks( $block ) . '</div>';
     628}
     629add_filter( 'woocommerce_gzd_legal_guarantee_html', __NAMESPACE__ . '\legal_guarantee_notice', 10, 3 );
     630
     631/**
     632 * Germanized prints its global notice for the location "footer" on wp_footer, after the footer of a block theme and so
     633 * outside every landmark. Its hook goes to leitvia_footer_end instead, which footer_end() fires inside the footer.
     634 *
     635 * @param array  $hook     Hook name and priority.
     636 * @param string $location Location of the notice.
     637 */
     638function legal_guarantee_footer_hook( $hook, $location = '' ): array {
     639        return 'footer' === $location ? array(
     640                'hook'     => 'leitvia_footer_end',
     641                'priority' => 10,
     642        ) : (array) $hook;
     643}
     644add_filter( 'woocommerce_gzd_legal_guarantee_location_hook', __NAMESPACE__ . '\legal_guarantee_footer_hook', 10, 2 );
     645
     646/**
     647 * Fires leitvia_footer_end at the end of every footer template part (tagName footer), inside the contentinfo landmark,
     648 * so plugins can add legal notes there. Nothing changes while no callback is hooked.
     649 *
     650 * @param string $html  Block HTML.
     651 * @param array  $block Parsed block.
     652 */
     653function footer_end( string $html, array $block ): string {
     654        $end = strrpos( $html, '</footer>' );
     655        if ( false === $end || 'footer' !== ( $block['attrs']['tagName'] ?? '' ) || ! has_action( 'leitvia_footer_end' ) ) {
     656                return $html;
     657        }
     658        ob_start();
     659        do_action( 'leitvia_footer_end' );
     660        return substr_replace( $html, (string) ob_get_clean(), $end, 0 );
     661}
     662add_filter( 'render_block_core/template-part', __NAMESPACE__ . '\footer_end', 10, 2 );
  • leitvia/1.2.11/leitvia-contract.json

    r355111 r356188  
    11{
    22        "$comment": "Machine-readable design contract of the Leitvia theme. Agents read this instead of guessing. Semver: major = removed or renamed role/pattern, minor = added, patch = descriptions. Explained for humans in design.md. A reference checker for compositionRules lives in the Leitvia monorepo and is not shipped with the theme. pageFrames: slots are unordered and may repeat; a page fills them with any number of patterns whose role the slot allows. Patterns with role frame (header, footer, hidden page parts) carry placeholder composition metadata that checks ignore.",
    3         "contractVersion": "1.10.0",
     3        "contractVersion": "1.13.3",
    44        "theme": "leitvia",
    55        "rules": [
    … …  
    339339                {
    340340                        "slug": "home",
    341                         "purpose": "Posts index with blog heading, featured sticky post and paginated list."
     341                        "purpose": "Posts index with blog heading (title and excerpt of the posts page when one is set), featured sticky post and paginated list with a continue reading link per post."
    342342                },
    343343                {
    344344                        "slug": "single",
    345                         "purpose": "Single post as an article with breadcrumbs above the one h1, byline, publish and update dates and a 16:9 featured image; Google News ready."
     345                        "purpose": "Single post as an article with breadcrumbs above the one h1, byline, publish and update dates and a 16:9 featured image; Google News ready. Below the post: author box, previous and next post, up to three related posts from the same categories and comments while they are open or exist."
    346346                },
    347347                {
    … …  
    423423                "styles": "Theme block styles are listed in blockStyles with purpose and allowed context. Pick a block style before adding a class, a color or custom CSS; set it as is-style-<name> in className.",
    424424                "search": "Every Search block is a search landmark named after its label. Give each search on a page its own label (theme patterns: Site search, Search products, Search documentation, Search this site); two searches with the same name cannot be told apart by screen reader users.",
    425                 "bindings": "The copyright line of the footer patterns binds its content to the source leitvia/site-meta (key copyright) and always shows the current year. Keep the binding; a typed year goes stale.",
     425                "bindings": "The copyright line of the footer patterns binds its content to the source leitvia/site-meta (key copyright) and always shows the current year. Keep the binding; a typed year goes stale. The image of a tile in leitvia/shop-category-tiles binds its url to leitvia/term-image, the image of the term; set the image on the category, not in the markup.",
    426426                "catalog": "Leitvia Studio, when active, publishes every block of Studio and its add-ons with attribute schema and usage rules at GET /wp-json/leitvia-studio/v1/blocks (users who can edit posts). Without Studio only core blocks and the theme block styles are available."
    427427        },
    … …  
    454454                        "block": "core/group",
    455455                        "name": "inverse",
    456                         "purpose": "Band that stays dark in every palette: ink with surface text in light palettes, surface-alt with ink text in dark ones. Use instead of an ink background; pairs in inversePairs.",
     456                        "purpose": "Band that stays dark in every palette: ink with surface text in light palettes, surface-alt with ink text and a hairline in stroke in dark ones, so the band stands apart from the page. Use instead of an ink background; pairs in inversePairs.",
    457457                        "context": "Full-width section bands for calls to action or proof; at most one or two per page, never nested."
    458458                },
    … …  
    494494                },
    495495                {
     496                        "block": "core/list",
     497                        "name": "download",
     498                        "purpose": "List of files to download: no bullets, a decorative file mark before each item, hairlines between items; the link of each item stands on its own line in bold.",
     499                        "context": "Lists where each item is one link to a file, named with format and size, followed by one sentence about the file; the pattern content-downloads uses it."
     500                },
     501                {
    496502                        "block": "core/paragraph",
    497503                        "name": "badge",
    … …  
    516522                        "purpose": "Comparison or price tables with a strong header row; scrolls sideways as a named region.",
    517523                        "context": "Tables that compare plans or options; keep the caption and a header row."
     524                },
     525                {
     526                        "block": "core/columns",
     527                        "name": "overlap",
     528                        "purpose": "The last column, a card, reaches into the column before it, an image; stacked on phones it rises over the lower edge of the image.",
     529                        "context": "Two columns of one image and one text card, as in hero-overlap; never with more than two columns."
     530                },
     531                {
     532                        "block": "core/group",
     533                        "name": "header-split",
     534                        "purpose": "Three columns of navigation, logo and action, with the logo exactly in the middle.",
     535                        "context": "The row of a header template part with navigation, site logo group and buttons, as in header-split; not for content."
     536                },
     537                {
     538                        "block": "core/buttons",
     539                        "name": "header-action",
     540                        "purpose": "The button beside the navigation of a header; hidden below 1024 px, where logo, menu items and button no longer fit in one row.",
     541                        "context": "Buttons in a header template part only; the target page must also be in the navigation."
    518542                }
    519543        ],
    … …  
    894918                },
    895919                {
     920                        "slug": "leitvia/content-downloads",
     921                        "title": "Downloads",
     922                        "description": "Heading and short intro above a list of files to download, one per row with a decorative file mark: the link names the file, its format and its size, a sentence below says what is inside. Use on product, service, press or documentation pages that offer documents.",
     923                        "area": "content",
     924                        "useWhen": "Documents visitors take away, such as product sheets, price lists, terms or a press kit, uploaded to the media library.",
     925                        "composition": {
     926                                "tone": "surface-alt",
     927                                "density": "dense",
     928                                "layout": "list",
     929                                "weight": "light",
     930                                "role": "detail",
     931                                "width": "reading"
     932                        },
     933                        "images": [],
     934                        "docs": {
     935                                "avoidWhen": "A single file inside running text; link it in the paragraph, or use a File block without its download button and with the file name, format and size as its text.",
     936                                "a11y": "A semantic list; each item has one text link that names the file, its format and its size, for example \"Price list 2026 (PDF, 180 KB)\", followed by one sentence on the content. The file mark is decorative CSS and never the only link. Take format and size from leitvia/list-media (mime, filesize); keep the link text unique on the page.",
     937                                "contentLength": {
     938                                        "heading": [
     939                                                20,
     940                                                50
     941                                        ],
     942                                        "text": [
     943                                                60,
     944                                                140
     945                                        ]
     946                                },
     947                                "replacedBy": null
     948                        }
     949                },
     950                {
    896951                        "slug": "leitvia/content-faq",
    897952                        "title": "Frequently asked questions",
    … …  
    12941349                },
    12951350                {
     1351                        "slug": "leitvia/content-video",
     1352                        "title": "Video with transcript",
     1353                        "description": "Heading and short introduction above a video with a poster image and a caption, followed by a folded transcript with the text of every scene. Use to explain a process in a short video that stays accessible without sound.",
     1354                        "area": "content",
     1355                        "useWhen": "Showing a process or a product step by step in a short video, with the same content as text for everyone who cannot or does not want to watch.",
     1356                        "composition": {
     1357                                "tone": "surface",
     1358                                "density": "regular",
     1359                                "layout": "list",
     1360                                "weight": "medium",
     1361                                "role": "detail",
     1362                                "width": "reading"
     1363                        },
     1364                        "images": [],
     1365                        "docs": {
     1366                                "avoidWhen": "The video has spoken words; then it needs captions in a text track as well, not only a transcript. Never let it play on its own.",
     1367                                "a11y": "The video has controls and no autoplay. The transcript in a native details element holds everything the video shows, so nothing depends on watching it. The poster is the image of the video, the caption says what it shows.",
     1368                                "contentLength": {
     1369                                        "heading": [
     1370                                                20,
     1371                                                70
     1372                                        ],
     1373                                        "text": [
     1374                                                80,
     1375                                                200
     1376                                        ]
     1377                                },
     1378                                "replacedBy": null
     1379                        }
     1380                },
     1381                {
    12961382                        "slug": "leitvia/cta-banner",
    12971383                        "title": "Call to action banner",
    … …  
    14531539                        "slug": "leitvia/footer-mega",
    14541540                        "title": "Footer mega",
    1455                         "description": "Large dark footer with a brand block of short pitch, trust facts and contact details, four link columns (four across or two by two, never three and one), legal navigation, social links, an empty Language switcher group for a WPML or Polylang switcher block and a back to top link. Use on product and company sites with many pages.",
     1541                        "description": "Large dark footer with a brand block of short pitch, trust facts and contact details, four link columns (four across or two by two, never three and one), legal navigation, social links, an empty Language switcher group for the language switcher block of a translation plugin and a back to top link. Use on product and company sites with many pages.",
    14561542                        "area": "footer",
    14571543                        "useWhen": "Product and company sites with many pages, legal links and social profiles.",
    … …  
    15761662                },
    15771663                {
     1664                        "slug": "leitvia/header-masthead",
     1665                        "title": "Header masthead",
     1666                        "description": "Newspaper masthead with a large centered site logo and the tagline below it, then the main navigation and the search between a heavy and a fine rule. Use for news sites and daily publications with a wide logo.",
     1667                        "area": "header",
     1668                        "useWhen": "News sites and daily publications whose wide logo should stand above the navigation like a masthead.",
     1669                        "composition": {
     1670                                "tone": "surface",
     1671                                "density": "regular",
     1672                                "layout": "centered",
     1673                                "weight": "heavy",
     1674                                "role": "frame",
     1675                                "width": "wide"
     1676                        },
     1677                        "images": [],
     1678                        "docs": {
     1679                                "avoidWhen": "Square or narrow logos and sites with many top level menu items; use header-default or header-search.",
     1680                                "a11y": "The site logo links home with the site name as its text alternative; the search has a label and the navigation is a labelled core navigation with a menu button on small screens.",
     1681                                "contentLength": {
     1682                                        "heading": null,
     1683                                        "text": null
     1684                                },
     1685                                "replacedBy": null
     1686                        }
     1687                },
     1688                {
    15781689                        "slug": "leitvia/header-minimal",
    15791690                        "title": "Header minimal",
    … …  
    16521763                                "woocommerce"
    16531764                        ]
     1765                },
     1766                {
     1767                        "slug": "leitvia/header-cta",
     1768                        "title": "Header with button",
     1769                        "description": "Site logo and title on the left, the main navigation and one button for the main action on the right, such as booking or getting in touch, with a fine line below. Below 1024 px the button gives way to the navigation. Use when one action matters on every page.",
     1770                        "area": "header",
     1771                        "useWhen": "Sites with one action that matters on every page, such as booking, a quote or getting in touch.",
     1772                        "composition": {
     1773                                "tone": "surface",
     1774                                "density": "regular",
     1775                                "layout": "split",
     1776                                "weight": "light",
     1777                                "role": "frame",
     1778                                "width": "wide"
     1779                        },
     1780                        "images": [],
     1781                        "docs": {
     1782                                "avoidWhen": "More than six top level menu items, or no single main action; use header-default.",
     1783                                "a11y": "Labelled navigation with a menu button on small screens; the button link names its target and is hidden below 1024 px, so the same page must be in the navigation.",
     1784                                "contentLength": {
     1785                                        "heading": null,
     1786                                        "text": null
     1787                                },
     1788                                "replacedBy": null
     1789                        }
     1790                },
     1791                {
     1792                        "slug": "leitvia/header-utility",
     1793                        "title": "Header with service bar",
     1794                        "description": "A slim dark bar above the header with opening hours on the left and a phone number and one more link on the right, then site logo and title, the main navigation and one button for the main action. Below 1024 px the button gives way to the navigation. Use for practices, trades and services that people call before they visit.",
     1795                        "area": "header",
     1796                        "useWhen": "Practices, trades, offices and services that people call or visit: opening hours and phone number on every page.",
     1797                        "composition": {
     1798                                "tone": "surface",
     1799                                "density": "regular",
     1800                                "layout": "split",
     1801                                "weight": "medium",
     1802                                "role": "frame",
     1803                                "width": "wide"
     1804                        },
     1805                        "images": [],
     1806                        "docs": {
     1807                                "avoidWhen": "Online only businesses, or when the bar would repeat the same facts as the header; use header-cta.",
     1808                                "a11y": "The bar is part of the banner landmark; its phone link uses tel: with the number in the link text. Labelled navigation with a menu button on small screens; the button is hidden below 1024 px, so its page must be in the navigation.",
     1809                                "contentLength": {
     1810                                        "heading": null,
     1811                                        "text": null
     1812                                },
     1813                                "replacedBy": null
     1814                        }
     1815                },
     1816                {
     1817                        "slug": "leitvia/header-split",
     1818                        "title": "Header with centered logo",
     1819                        "description": "The main navigation on the left, site logo and title exactly in the middle and one button on the right, with a fine line below. On phones the menu button sits on the left and the logo stays in the middle. Use for restaurants, studios, firms and brands whose logo should lead.",
     1820                        "area": "header",
     1821                        "useWhen": "Restaurants, studios, firms and brands with a strong logo and four or five menu items.",
     1822                        "composition": {
     1823                                "tone": "surface",
     1824                                "density": "regular",
     1825                                "layout": "centered",
     1826                                "weight": "light",
     1827                                "role": "frame",
     1828                                "width": "wide"
     1829                        },
     1830                        "images": [],
     1831                        "docs": {
     1832                                "avoidWhen": "More than five top level menu items; the left column wraps. Long site titles without a logo.",
     1833                                "a11y": "Labelled navigation with a menu button on small screens, where it sits on the left; the button is hidden below 1024 px, so its page must be in the navigation.",
     1834                                "contentLength": {
     1835                                        "heading": null,
     1836                                        "text": null
     1837                                },
     1838                                "replacedBy": null
     1839                        }
    16541840                },
    16551841                {
    … …  
    17551941                },
    17561942                {
     1943                        "slug": "leitvia/hero-search",
     1944                        "title": "Hero with search",
     1945                        "description": "Page intro that leads with search: a large heading, a wide search field with a visible label, a short lead and up to three buttons to the pages most people open first. Use at the top of documentation, help centers and knowledge bases.",
     1946                        "area": "hero",
     1947                        "useWhen": "Home page of documentation, a help center or a knowledge base, where most visitors arrive with a question.",
     1948                        "composition": {
     1949                                "tone": "surface",
     1950                                "density": "airy",
     1951                                "layout": "asymmetric",
     1952                                "weight": "heavy",
     1953                                "role": "hook",
     1954                                "width": "wide"
     1955                        },
     1956                        "images": [],
     1957                        "docs": {
     1958                                "avoidWhen": "Sites with few pages, where search finds little; or a header that already holds the only search field visitors need.",
     1959                                "a11y": "Holds the only h1. The search field keeps its visible label, so a second search in the header stays distinguishable; the buttons name their target pages.",
     1960                                "contentLength": {
     1961                                        "heading": [
     1962                                                25,
     1963                                                60
     1964                                        ],
     1965                                        "text": [
     1966                                                80,
     1967                                                180
     1968                                        ]
     1969                                },
     1970                                "replacedBy": null
     1971                        }
     1972                },
     1973                {
    17571974                        "slug": "leitvia/hero-split-image",
    17581975                        "title": "Hero split with image",
    … …  
    17942011                },
    17952012                {
     2013                        "slug": "leitvia/hero-overlap",
     2014                        "title": "Hero with card over image",
     2015                        "description": "A large image on the left and a text card on the right that reaches into the image, with eyebrow, heading, lead text and two buttons; on phones the card overlaps the lower edge of the image. Use when a photo should lead but the text must stay on a calm background.",
     2016                        "area": "hero",
     2017                        "useWhen": "Home and service pages where a photo should lead but the message must stay on a calm background, never on the picture.",
     2018                        "composition": {
     2019                                "tone": "surface",
     2020                                "density": "regular",
     2021                                "layout": "overlap",
     2022                                "weight": "heavy",
     2023                                "role": "hook",
     2024                                "width": "wide"
     2025                        },
     2026                        "images": [
     2027                                {
     2028                                        "aspectRatio": "4/3",
     2029                                        "displayWidth": "52rem",
     2030                                        "recommendedSize": "1600x1200",
     2031                                        "count": 1,
     2032                                        "source": "inline"
     2033                                }
     2034                        ],
     2035                        "docs": {
     2036                                "avoidWhen": "The next section is also split or overlapping, or no meaningful photo exists.",
     2037                                "a11y": "Holds the only h1, in the card, so text never sits on the image; the image needs alt text when it shows what the page offers.",
     2038                                "contentLength": {
     2039                                        "heading": [
     2040                                                25,
     2041                                                60
     2042                                        ],
     2043                                        "text": [
     2044                                                60,
     2045                                                140
     2046                                        ]
     2047                                },
     2048                                "replacedBy": null
     2049                        }
     2050                },
     2051                {
     2052                        "slug": "leitvia/hero-teaser-trio",
     2053                        "title": "Hero with three teasers",
     2054                        "description": "Page intro as three large picture teasers: heading and lead text in one row above three tall images, each with a number, a linked title and one sentence below. Use on home pages that lead straight into three services, stories or offers instead of one big message.",
     2055                        "area": "hero",
     2056                        "useWhen": "Home pages that lead straight into three services, stories or offers of equal weight.",
     2057                        "composition": {
     2058                                "tone": "surface",
     2059                                "density": "regular",
     2060                                "layout": "grid",
     2061                                "weight": "heavy",
     2062                                "role": "hook",
     2063                                "width": "wide"
     2064                        },
     2065                        "images": [
     2066                                {
     2067                                        "aspectRatio": "3/4",
     2068                                        "displayWidth": "25rem",
     2069                                        "recommendedSize": "900x1200",
     2070                                        "count": 3,
     2071                                        "source": "inline"
     2072                                }
     2073                        ],
     2074                        "docs": {
     2075                                "avoidWhen": "Only one offer, or teasers without strong photos; follow it with a list or text section, not with another grid.",
     2076                                "a11y": "Holds the only h1; teaser titles are h2 links that name their target. Each image needs alt text unless the title says everything it shows.",
     2077                                "contentLength": {
     2078                                        "heading": [
     2079                                                20,
     2080                                                50
     2081                                        ],
     2082                                        "text": [
     2083                                                80,
     2084                                                140
     2085                                        ]
     2086                                },
     2087                                "replacedBy": null
     2088                        }
     2089                },
     2090                {
    17962091                        "slug": "leitvia/page-accessibility-statement",
    17972092                        "title": "Accessibility statement",
    … …  
    18712166                        "slug": "leitvia/hidden-page-blog-heading",
    18722167                        "title": "Blog heading",
    1873                         "description": "Page heading with a short lead for the posts index.",
     2168                        "description": "Page heading with a short lead for the posts index. With a posts page set in the reading settings, its title and excerpt replace the default texts.",
    18742169                        "area": "page",
    18752170                        "useWhen": "Inserted by the home template above the posts index.",
    … …  
    20252320                },
    20262321                {
     2322                        "slug": "leitvia/hidden-page-post-author",
     2323                        "title": "About the author",
     2324                        "description": "Author box below a single post: a heading, the linked name of the author and the biographical info of the profile. No avatar, so no request goes to Gravatar.",
     2325                        "area": "page",
     2326                        "useWhen": "Inserted by the single template below the post.",
     2327                        "composition": {
     2328                                "tone": "surface",
     2329                                "density": "regular",
     2330                                "layout": "list",
     2331                                "weight": "light",
     2332                                "role": "frame",
     2333                                "width": "reading"
     2334                        },
     2335                        "images": [],
     2336                        "docs": {
     2337                                "avoidWhen": "Never insert manually; it is hidden from the inserter and owned by a template.",
     2338                                "a11y": "An aside landmark named About the author with an h2; no avatar, so nothing is requested from Gravatar. The biography comes from the user profile and stays empty when the profile has none.",
     2339                                "contentLength": {
     2340                                        "heading": null,
     2341                                        "text": null
     2342                                },
     2343                                "replacedBy": null
     2344                        }
     2345                },
     2346                {
    20272347                        "slug": "leitvia/hidden-page-post-byline",
    20282348                        "title": "Post byline",
    … …  
    20502370                },
    20512371                {
     2372                        "slug": "leitvia/hidden-page-post-navigation",
     2373                        "title": "Post navigation",
     2374                        "description": "Links to the previous and the next post below a single post, each named with its direction and the post title.",
     2375                        "area": "page",
     2376                        "useWhen": "Inserted by the single template below the post.",
     2377                        "composition": {
     2378                                "tone": "surface",
     2379                                "density": "regular",
     2380                                "layout": "list",
     2381                                "weight": "light",
     2382                                "role": "frame",
     2383                                "width": "reading"
     2384                        },
     2385                        "images": [],
     2386                        "docs": {
     2387                                "avoidWhen": "Never insert manually; it is hidden from the inserter and owned by a template.",
     2388                                "a11y": "A nav landmark named More articles; each link names its direction and the post title, for example Previous article: <title>. Missing neighbours render nothing.",
     2389                                "contentLength": {
     2390                                        "heading": null,
     2391                                        "text": null
     2392                                },
     2393                                "replacedBy": null
     2394                        }
     2395                },
     2396                {
    20522397                        "slug": "leitvia/hidden-page-product-details",
    20532398                        "title": "Product details",
    … …  
    20762421                                "woocommerce"
    20772422                        ]
     2423                },
     2424                {
     2425                        "slug": "leitvia/hidden-page-read-more",
     2426                        "title": "Continue reading link",
     2427                        "description": "Link to the full post below its excerpt in the post lists of the blog, archive, author and search templates. Core adds the post title for screen readers.",
     2428                        "area": "page",
     2429                        "useWhen": "Inserted by the blog, archive, author and search templates below each excerpt.",
     2430                        "composition": {
     2431                                "tone": "surface",
     2432                                "density": "regular",
     2433                                "layout": "list",
     2434                                "weight": "light",
     2435                                "role": "frame",
     2436                                "width": "reading"
     2437                        },
     2438                        "images": [],
     2439                        "docs": {
     2440                                "avoidWhen": "Never insert manually; it is hidden from the inserter and owned by a template.",
     2441                                "a11y": "The visible text Continue reading is completed by the post title for screen readers by core, so every link has a unique name.",
     2442                                "contentLength": {
     2443                                        "heading": null,
     2444                                        "text": null
     2445                                },
     2446                                "replacedBy": null
     2447                        }
     2448                },
     2449                {
     2450                        "slug": "leitvia/hidden-page-related-posts",
     2451                        "title": "Related posts",
     2452                        "description": "Up to three other posts from the categories of the current post below a single post, each with linked title and date. Renders nothing when there are none.",
     2453                        "area": "page",
     2454                        "useWhen": "Inserted by the single template below the post.",
     2455                        "composition": {
     2456                                "tone": "surface",
     2457                                "density": "regular",
     2458                                "layout": "list",
     2459                                "weight": "light",
     2460                                "role": "frame",
     2461                                "width": "reading"
     2462                        },
     2463                        "images": [],
     2464                        "docs": {
     2465                                "avoidWhen": "Never insert manually; it is hidden from the inserter and owned by a template.",
     2466                                "a11y": "An h2 above up to three h3 title links with dates as time elements; the whole section is left out when no other post matches.",
     2467                                "contentLength": {
     2468                                        "heading": null,
     2469                                        "text": null
     2470                                },
     2471                                "replacedBy": null
     2472                        }
    20782473                },
    20792474                {
    … …  
    24382833                },
    24392834                {
     2835                        "slug": "leitvia/teaser-front-page",
     2836                        "title": "Front page",
     2837                        "description": "Newspaper front page in three columns under a page heading: the sticky lead story wide with image, desk, headline, excerpt, author and date, beside it four headlines in brief and three more stories with small images. Use as the top of the home page of a news site that marks its lead story as sticky.",
     2838                        "area": "teaser",
     2839                        "useWhen": "The first section of the home page of a news site or daily publication with one sticky lead story and at least seven more posts.",
     2840                        "composition": {
     2841                                "tone": "surface",
     2842                                "density": "dense",
     2843                                "layout": "asymmetric",
     2844                                "weight": "heavy",
     2845                                "role": "hook",
     2846                                "width": "wide"
     2847                        },
     2848                        "images": [
     2849                                {
     2850                                        "aspectRatio": "3/2",
     2851                                        "displayWidth": "44rem",
     2852                                        "recommendedSize": "1600x1067",
     2853                                        "count": 1,
     2854                                        "source": "featured-image"
     2855                                },
     2856                                {
     2857                                        "aspectRatio": "16/9",
     2858                                        "displayWidth": "17rem",
     2859                                        "recommendedSize": "800x450",
     2860                                        "count": 1,
     2861                                        "source": "featured-image"
     2862                                }
     2863                        ],
     2864                        "docs": {
     2865                                "avoidWhen": "Sites without a sticky post, the lead column then stays empty; magazines that want one story only, use teaser-featured-post.",
     2866                                "a11y": "The page heading is the h1 of the home page, so the page needs no other h1. The lead headline is an h2, the two side columns have an h2 each with h3 headlines. The lead comes first in the reading order; the queries skip sticky posts and each other, so no story appears twice.",
     2867                                "contentLength": {
     2868                                        "heading": [
     2869                                                20,
     2870                                                60
     2871                                        ],
     2872                                        "text": [
     2873                                                60,
     2874                                                200
     2875                                        ]
     2876                                },
     2877                                "replacedBy": null
     2878                        }
     2879                },
     2880                {
    24402881                        "slug": "leitvia/teaser-posts-badge",
    24412882                        "title": "Posts with category badges",
    … …  
    26193060                        "docs": {
    26203061                                "avoidWhen": "Another ink section is adjacent, or the promises are not true for every order; never add logos of payment providers.",
    2621                                 "a11y": "Each promise is an h3 with one line of text; payment methods are plain text, so screen readers read them without image alt texts.",
     3062                                "a11y": "Each promise is an h2 with one line of text, so the band fits right below the h1 of a hero and after any other section; payment methods are plain text, so screen readers read them without image alt texts.",
    26223063                                "contentLength": {
    26233064                                        "heading": [
    … …  
    26393080                        "slug": "leitvia/shop-category-tiles",
    26403081                        "title": "Shop category tiles",
    2641                         "description": "Heading above one tile per product category of the shop, three across on wide screens, each with the linked category name and its description. The tiles follow the categories of the shop on their own. Use on a shop home page to lead visitors into the range.",
     3082                        "description": "Heading above one tile per product category of the shop, three across on wide screens, each with the image of the category when it has one, the linked category name and its description. The tiles follow the categories of the shop on their own. Use on a shop home page to lead visitors into the range.",
    26423083                        "area": "teaser",
    26433084                        "useWhen": "Shop home pages that lead into the range by category; the tiles list the product categories that hold products.",
    … …  
    26503091                                "width": "wide"
    26513092                        },
    2652                         "images": [],
     3093                        "images": [
     3094                                {
     3095                                        "aspectRatio": "4/3",
     3096                                        "displayWidth": "24rem",
     3097                                        "recommendedSize": "768x576",
     3098                                        "count": 1,
     3099                                        "source": "inline"
     3100                                }
     3101                        ],
    26533102                        "docs": {
    26543103                                "avoidWhen": "The shop has only one category, or a category page (its subcategories belong into the archive itself).",
    2655                                 "a11y": "Category names are linked h3; write a category description in the shop, else the tile shows the name only.",
     3104                                "a11y": "Category names are linked h3; write a category description in the shop, else the tile shows the name only. The image is the category image (leitvia/update-product-category with image), bound through leitvia/term-image and decorative next to the linked name; without one the tile has no image.",
    26563105                                "contentLength": {
    26573106                                        "heading": [
    … …  
    27883237                        "images": [],
    27893238                        "docs": {
    2790                                 "avoidWhen": "Shops without Germanized; the pattern is then not registered and the product template shows nothing in its place. With German Market use its own blocks.",
     3239                                "avoidWhen": "Shops without Germanized; the pattern is then not registered and the product template shows nothing in its place. German Market prints its own price details after the price by itself.",
    27913240                                "a11y": "Plain text lines in the muted role that keep the meta contrast; the shipping note links to the shipping costs page with a descriptive link text from Germanized.",
     3241                                "contentLength": {
     3242                                        "heading": null,
     3243                                        "text": null
     3244                                },
     3245                                "replacedBy": null
     3246                        },
     3247                        "requires": [
     3248                                "woocommerce",
     3249                                "woocommerce-germanized"
     3250                        ]
     3251                },
     3252                {
     3253                        "slug": "leitvia/shop-legal-guarantee",
     3254                        "title": "Legal guarantee notice",
     3255                        "description": "The EU notice on the legal guarantee from Germanized, as a disclosure with a text summary, the official label and a link to europa.eu. Shows only while the notice is switched on in Germanized and the product is not virtual. Available only while Germanized is active. Use in the single product template below the add to cart form.",
     3256                        "area": "page",
     3257                        "useWhen": "In the single product template below the add to cart form (it is placed there already), while Germanized is active and its notice on the legal guarantee is switched on.",
     3258                        "composition": {
     3259                                "tone": "surface",
     3260                                "density": "dense",
     3261                                "layout": "list",
     3262                                "weight": "light",
     3263                                "role": "frame",
     3264                                "width": "reading"
     3265                        },
     3266                        "images": [],
     3267                        "docs": {
     3268                                "avoidWhen": "Product grids, where one disclosure per product is noise, and shops without Germanized; the pattern is then not registered and the product template shows nothing in its place.",
     3269                                "a11y": "A native disclosure (details and summary) with a text summary, operable by keyboard without script; the label image carries Germanized's alt text, and a text link leads to the full notice on europa.eu. The theme renders every variant of Germanized this way, also in cart, checkout and the shortcode.",
    27923270                                "contentLength": {
    27933271                                        "heading": null,
    … …  
    28353313                },
    28363314                {
     3315                        "slug": "leitvia-studio/content-spotlight",
     3316                        "title": "Annotated image",
     3317                        "description": "Heading with a short introduction beside it on a tinted band and a wide image with numbered points that each open a note. Use to explain the parts of a product, a room, a building or a page.",
     3318                        "area": "content",
     3319                        "useWhen": "A picture that needs explaining part by part, such as a product, a floor plan, a facade or a screenshot of a page, typically in the context step of a landing page.",
     3320                        "composition": {
     3321                                "tone": "surface-alt",
     3322                                "density": "regular",
     3323                                "layout": "asymmetric",
     3324                                "weight": "medium",
     3325                                "role": "context",
     3326                                "width": "wide"
     3327                        },
     3328                        "images": [
     3329                                {
     3330                                        "aspectRatio": "3/2",
     3331                                        "displayWidth": "80rem",
     3332                                        "recommendedSize": "2400x1600",
     3333                                        "count": 1,
     3334                                        "source": "inline"
     3335                                }
     3336                        ],
     3337                        "docs": {
     3338                                "avoidWhen": "The picture explains itself or needs more than six points; then use a list or the feature grid. Needs Leitvia Studio for the spotlight block.",
     3339                                "a11y": "Each point is a disclosure with a visible number and a name that screen readers announce; on narrow screens the notes follow the image as a list in the same order. The image keeps a meaningful alt text, the notes add detail and never the only description.",
     3340                                "contentLength": {
     3341                                        "heading": [
     3342                                                30,
     3343                                                70
     3344                                        ],
     3345                                        "text": [
     3346                                                60,
     3347                                                200
     3348                                        ]
     3349                                },
     3350                                "replacedBy": null
     3351                        }
     3352                },
     3353                {
    28373354                        "slug": "leitvia-studio/content-story-highlight",
    28383355                        "title": "Story with highlight",
    … …  
    28663383                },
    28673384                {
     3385                        "slug": "leitvia-studio/content-timeline",
     3386                        "title": "Timeline with introduction",
     3387                        "description": "Heading, short introduction and a link on the left, five dated entries of a timeline on the right. Use to tell how a project, a decision or a story developed over time.",
     3388                        "area": "content",
     3389                        "useWhen": "Background to a news story, the history of a project or an organization, any sequence of dated steps that a reader should follow in order.",
     3390                        "composition": {
     3391                                "tone": "surface-alt",
     3392                                "density": "regular",
     3393                                "layout": "asymmetric",
     3394                                "weight": "medium",
     3395                                "role": "context",
     3396                                "width": "wide"
     3397                        },
     3398                        "images": [],
     3399                        "docs": {
     3400                                "avoidWhen": "Steps without dates; use content-steps instead. More than seven entries make the band longer than the screen. Needs Leitvia Studio for the timeline block.",
     3401                                "a11y": "The timeline is an ordered list; every entry has a time element with a machine readable date and an h3 under the section h2. Line and dots are decoration.",
     3402                                "contentLength": {
     3403                                        "heading": [
     3404                                                20,
     3405                                                60
     3406                                        ],
     3407                                        "text": [
     3408                                                40,
     3409                                                140
     3410                                        ]
     3411                                },
     3412                                "replacedBy": null
     3413                        }
     3414                },
     3415                {
     3416                        "slug": "leitvia-studio/content-entry-facts",
     3417                        "title": "Entry facts",
     3418                        "description": "The facts of one entry as a ruled list of label and value, such as date, price and free places, each value bound to a field of the content model. Use in the content of an entry page below the introduction.",
     3419                        "area": "content",
     3420                        "useWhen": "Entry page of a post type of the content model, such as a course or an event. Copy the markup into the content of the entry with leitvia/create-content: one row per field, the label as text, the value bound to leitvia/meta with the field key (suffix adds a unit or currency such as \" €\"). It renders as a description list.",
     3421                        "composition": {
     3422                                "tone": "surface",
     3423                                "density": "dense",
     3424                                "layout": "list",
     3425                                "weight": "light",
     3426                                "role": "detail",
     3427                                "width": "reading"
     3428                        },
     3429                        "images": [],
     3430                        "docs": {
     3431                                "avoidWhen": "Pages without an entry of the content model as context; the bound values stay empty there. Prices of products, which the shop shows.",
     3432                                "a11y": "Renders as a description list: each label a term, each value its description, in reading order. Keep exactly two paragraphs per row, the label first.",
     3433                                "contentLength": {
     3434                                        "heading": null,
     3435                                        "text": [
     3436                                                1,
     3437                                                40
     3438                                        ]
     3439                                },
     3440                                "replacedBy": null
     3441                        }
     3442                },
     3443                {
     3444                        "slug": "leitvia-studio/teaser-type-entries",
     3445                        "title": "Entries of a type",
     3446                        "description": "Heading above the latest entries of one post type as a ruled list, each with its linked title and excerpt. Use as the overview of courses, events or other entries of the content model, with their fields in each row.",
     3447                        "area": "teaser",
     3448                        "useWhen": "Overview page of a post type of the content model, such as courses or events. Build it with leitvia/create-content from this markup: set query.postType to the type and add a paragraph per field bound to leitvia/meta.",
     3449                        "composition": {
     3450                                "tone": "surface",
     3451                                "density": "dense",
     3452                                "layout": "list",
     3453                                "weight": "light",
     3454                                "role": "context",
     3455                                "width": "wide"
     3456                        },
     3457                        "images": [],
     3458                        "docs": {
     3459                                "avoidWhen": "Blog posts; use teaser-posts-list or teaser-posts-grid. Unchanged through compose-page it lists blog posts, not the entries of a type.",
     3460                                "a11y": "Titles are h3 links under the section h2; field values follow their title in reading order. A value that is unclear on its own, such as a bare number, sits in a row with a label such as Free places.",
     3461                                "contentLength": {
     3462                                        "heading": [
     3463                                                10,
     3464                                                40
     3465                                        ],
     3466                                        "text": null
     3467                                },
     3468                                "replacedBy": null
     3469                        }
     3470                },
     3471                {
    28683472                        "slug": "leitvia-studio/offer-pricing-plans",
    28693473                        "title": "Pricing plans with comparison",
    … …  
    29223526                                                30,
    29233527                                                80
     3528                                        ]
     3529                                },
     3530                                "replacedBy": null
     3531                        }
     3532                },
     3533                {
     3534                        "slug": "leitvia-studio/content-spotlight-scene",
     3535                        "title": "Scene with points",
     3536                        "description": "Heading and short introduction above a wide picture with four numbered points; each point opens a name, one line and a link. Use to show the products in a room, on a table or on a person, or the parts of a product in their place.",
     3537                        "area": "content",
     3538                        "useWhen": "A shop or product page where one photo shows several products or parts that each deserve a name and a link.",
     3539                        "composition": {
     3540                                "tone": "surface-alt",
     3541                                "density": "regular",
     3542                                "layout": "overlap",
     3543                                "weight": "heavy",
     3544                                "role": "detail",
     3545                                "width": "wide"
     3546                        },
     3547                        "images": [
     3548                                {
     3549                                        "aspectRatio": "intrinsic",
     3550                                        "displayWidth": "80rem",
     3551                                        "recommendedSize": "2560x1707",
     3552                                        "count": 1,
     3553                                        "source": "inline"
     3554                                }
     3555                        ],
     3556                        "docs": {
     3557                                "avoidWhen": "Pictures without distinct objects, or more than six points; use an image with a caption or a product grid. Needs Leitvia Studio for the spotlight block.",
     3558                                "a11y": "Every point is a disclosure with its name as the accessible name; the number is hidden from assistive technology. Below 782 px the points follow the picture as a list in the same order, so nothing depends on the picture.",
     3559                                "contentLength": {
     3560                                        "heading": [
     3561                                                30,
     3562                                                70
     3563                                        ],
     3564                                        "text": [
     3565                                                60,
     3566                                                140
    29243567                                        ]
    29253568                                },
  • leitvia/1.2.11/patterns/content-compare-two.php

    r355111 r356188  
    6262                </div>
    6363                <!-- /wp:group -->
    64                 <!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|l","right":"var:preset|spacing|l","bottom":"var:preset|spacing|l","left":"var:preset|spacing|l"},"blockGap":"var:preset|spacing|m"}},"backgroundColor":"ink","textColor":"surface"} -->
    65                 <div class="wp-block-group has-surface-color has-ink-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--l);padding-right:var(--wp--preset--spacing--l);padding-bottom:var(--wp--preset--spacing--l);padding-left:var(--wp--preset--spacing--l)">
     64                <!-- wp:group {"className":"is-style-inverse","style":{"spacing":{"padding":{"top":"var:preset|spacing|l","right":"var:preset|spacing|l","bottom":"var:preset|spacing|l","left":"var:preset|spacing|l"},"blockGap":"var:preset|spacing|m"}}} -->
     65                <div class="wp-block-group is-style-inverse" style="padding-top:var(--wp--preset--spacing--l);padding-right:var(--wp--preset--spacing--l);padding-bottom:var(--wp--preset--spacing--l);padding-left:var(--wp--preset--spacing--l)">
    6666                        <!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|s"}},"layout":{"type":"flex","flexWrap":"wrap","verticalAlignment":"center"}} -->
    6767                        <div class="wp-block-group">
  • leitvia/1.2.11/patterns/content-price-list.php

    r355111 r356188  
    3636        <!-- /wp:table -->
    3737        <!-- wp:paragraph {"textColor":"ink-muted","fontSize":"meta"} -->
    38         <p class="has-ink-muted-color has-text-color has-meta-font-size"><?php esc_html_e( 'Source: Leitvia demo price list, as of 1 October 2026. Prices may change for new contracts; running contracts keep their price until renewal.', 'leitvia' ); ?></p>
     38        <p class="has-ink-muted-color has-text-color has-meta-font-size"><?php esc_html_e( 'Source: sample price list, as of 1 October 2026. Prices may change for new contracts; running contracts keep their price until renewal.', 'leitvia' ); ?></p>
    3939        <!-- /wp:paragraph -->
    4040</div>
  • leitvia/1.2.11/patterns/footer-mega.php

    r355111 r356188  
    44 * Slug: leitvia/footer-mega
    55 * Categories: footer
    6  * Description: Large dark footer with a brand block of short pitch, trust facts and contact details, four link columns (four across or two by two, never three and one), legal navigation, social links, an empty Language switcher group for a WPML or Polylang switcher block and a back to top link. Use on product and company sites with many pages.
     6 * Description: Large dark footer with a brand block of short pitch, trust facts and contact details, four link columns (four across or two by two, never three and one), legal navigation, social links, an empty Language switcher group for the language switcher block of a translation plugin and a back to top link. Use on product and company sites with many pages.
    77 * Keywords: footer, mega footer, sitemap, contact, legal, social
    88 * Block Types: core/template-part/footer
    … …  
    1313
    1414?>
    15 <!-- wp:group {"metadata":{"name":"Footer"},"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|xl","bottom":"var:preset|spacing|xl"},"blockGap":"var:preset|spacing|xl"}},"backgroundColor":"ink","textColor":"surface","layout":{"type":"constrained"}} -->
    16 <div class="wp-block-group alignfull has-surface-color has-ink-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--xl);padding-bottom:var(--wp--preset--spacing--xl)">
     15<!-- wp:group {"metadata":{"name":"Footer"},"align":"full","className":"is-style-inverse","style":{"spacing":{"padding":{"top":"var:preset|spacing|xl","bottom":"var:preset|spacing|xl"},"blockGap":"var:preset|spacing|xl"}},"layout":{"type":"constrained"}} -->
     16<div class="wp-block-group alignfull is-style-inverse" style="padding-top:var(--wp--preset--spacing--xl);padding-bottom:var(--wp--preset--spacing--xl)">
    1717        <!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"top":"var:preset|spacing|xl","left":"var:preset|spacing|xxl"}}}} -->
    1818        <div class="wp-block-columns alignwide">
    … …  
    189189                                <!-- wp:navigation-link {"label":"<?php echo esc_attr__( 'Data processing agreement', 'leitvia' ); ?>","url":"#","kind":"custom"} /-->
    190190                        <!-- /wp:navigation -->
    191                         <!-- wp:social-links {"iconColor":"surface","showLabels":true,"className":"is-style-logos-only","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|m"}}}} -->
     191                        <!-- wp:social-links {"showLabels":true,"className":"is-style-logos-only","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|m"}}}} -->
    192192                        <ul class="wp-block-social-links has-visible-labels is-style-logos-only">
    193193                                <!-- wp:social-link {"url":"#","service":"linkedin"} /-->
  • leitvia/1.2.11/patterns/hidden-page-blog-heading.php

    r355111 r356188  
    44 * Slug: leitvia/hidden-page-blog-heading
    55 * Categories: text
    6  * Description: Page heading with a short lead for the posts index.
     6 * Description: Page heading with a short lead for the posts index. With a posts page set in the reading settings, its title and excerpt replace the default texts.
    77 * Keywords: blog, heading, posts, intro
    88 * Inserter: no
    … …  
    1111 */
    1212
     13// A posts page such as "Journal" names the blog; its title and excerpt are read when the template renders.
     14$leitvia_posts_page = (int) get_option( 'page_for_posts' );
     15$leitvia_blog_title = $leitvia_posts_page ? get_the_title( $leitvia_posts_page ) : '';
     16$leitvia_blog_lead  = $leitvia_posts_page && has_excerpt( $leitvia_posts_page ) ? get_the_excerpt( $leitvia_posts_page ) : '';
     17
    1318?>
    1419<!-- wp:heading {"level":1} -->
    15 <h1 class="wp-block-heading"><?php esc_html_e( 'Latest writing', 'leitvia' ); ?></h1>
     20<h1 class="wp-block-heading"><?php echo esc_html( '' !== $leitvia_blog_title ? $leitvia_blog_title : __( 'Latest writing', 'leitvia' ) ); ?></h1>
    1621<!-- /wp:heading -->
    1722<!-- wp:paragraph {"textColor":"ink-muted","fontSize":"lead"} -->
    18 <p class="has-ink-muted-color has-text-color has-lead-font-size"><?php esc_html_e( 'New essays, projects and notes, newest first.', 'leitvia' ); ?></p>
     23<p class="has-ink-muted-color has-text-color has-lead-font-size"><?php echo esc_html( '' !== $leitvia_blog_lead ? $leitvia_blog_lead : __( 'New essays, projects and notes, newest first.', 'leitvia' ) ); ?></p>
    1924<!-- /wp:paragraph -->
  • leitvia/1.2.11/patterns/shop-category-tiles.php

    r355111 r356188  
    44 * Slug: leitvia/shop-category-tiles
    55 * Categories: leitvia-shop
    6  * Description: Heading above one tile per product category of the shop, three across on wide screens, each with the linked category name and its description. The tiles follow the categories of the shop on their own. Use on a shop home page to lead visitors into the range.
     6 * Description: Heading above one tile per product category of the shop, three across on wide screens, each with the image of the category when it has one, the linked category name and its description. The tiles follow the categories of the shop on their own. Use on a shop home page to lead visitors into the range.
    77 * Keywords: shop, categories, product categories, tiles, range, woocommerce
    88 * Viewport Width: 1400
    … …  
    2222                        <!-- wp:group {"style":{"border":{"radius":"var:preset|border-radius|s"},"spacing":{"padding":{"top":"var:preset|spacing|m","right":"var:preset|spacing|m","bottom":"var:preset|spacing|m","left":"var:preset|spacing|m"},"blockGap":"var:preset|spacing|xs"}},"backgroundColor":"surface-alt"} -->
    2323                        <div class="wp-block-group has-surface-alt-background-color has-background" style="border-radius:var(--wp--preset--border-radius--s);padding-top:var(--wp--preset--spacing--m);padding-right:var(--wp--preset--spacing--m);padding-bottom:var(--wp--preset--spacing--m);padding-left:var(--wp--preset--spacing--m)">
     24                                <!-- wp:image {"aspectRatio":"4/3","scale":"cover","sizeSlug":"medium_large","linkDestination":"none","metadata":{"bindings":{"url":{"source":"leitvia/term-image"}},"leitviaDecorative":true}} -->
     25                                <figure class="wp-block-image size-medium_large"><img alt="" style="aspect-ratio:4/3;object-fit:cover"/></figure>
     26                                <!-- /wp:image -->
    2427                                <!-- wp:term-name {"level":3,"isLink":true,"fontSize":"heading-s"} /-->
    2528                                <!-- wp:term-description {"textColor":"ink-muted","fontSize":"meta"} /-->
  • leitvia/1.2.11/patterns/shop-usp-bar.php

    r355111 r356188  
    1818                <!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|xxs"}}} -->
    1919                <div class="wp-block-group">
    20                         <!-- wp:heading {"level":3,"fontSize":"body"} -->
    21                         <h3 class="wp-block-heading has-body-font-size"><?php esc_html_e( 'Free shipping from 50 euros', 'leitvia' ); ?></h3>
     20                        <!-- wp:heading {"fontSize":"body"} -->
     21                        <h2 class="wp-block-heading has-body-font-size"><?php esc_html_e( 'Free shipping from 50 euros', 'leitvia' ); ?></h2>
    2222                        <!-- /wp:heading -->
    2323                        <!-- wp:paragraph {"fontSize":"meta"} -->
    … …  
    2828                <!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|xxs"}}} -->
    2929                <div class="wp-block-group">
    30                         <!-- wp:heading {"level":3,"fontSize":"body"} -->
    31                         <h3 class="wp-block-heading has-body-font-size"><?php esc_html_e( '30 days to return', 'leitvia' ); ?></h3>
     30                        <!-- wp:heading {"fontSize":"body"} -->
     31                        <h2 class="wp-block-heading has-body-font-size"><?php esc_html_e( '30 days to return', 'leitvia' ); ?></h2>
    3232                        <!-- /wp:heading -->
    3333                        <!-- wp:paragraph {"fontSize":"meta"} -->
    … …  
    3838                <!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|xxs"}}} -->
    3939                <div class="wp-block-group">
    40                         <!-- wp:heading {"level":3,"fontSize":"body"} -->
    41                         <h3 class="wp-block-heading has-body-font-size"><?php esc_html_e( 'Pay the way you like', 'leitvia' ); ?></h3>
     40                        <!-- wp:heading {"fontSize":"body"} -->
     41                        <h2 class="wp-block-heading has-body-font-size"><?php esc_html_e( 'Pay the way you like', 'leitvia' ); ?></h2>
    4242                        <!-- /wp:heading -->
    4343                        <!-- wp:paragraph {"fontSize":"meta"} -->
  • leitvia/1.2.11/readme.txt

    r355111 r356188  
    44Tested up to: 7.1
    55Requires PHP: 8.2
    6 Stable tag: 1.0.2
     6Stable tag: 1.2.11
    77License: GNU General Public License v2 or later
    88License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    2727* Form fields in search and comments have visible labels, required fields are marked and personal data fields declare their purpose (autocomplete).
    2828* A pattern "Accessibility statement" gives site owners a template with the details BITV 2.0 and the European Accessibility Act require.
    29 * The page template "Page in easy language" sets pages in easy language (Leichte Sprache) in a narrower column with larger text, line height 1.6, left aligned and without hyphenation. Leitvia Studio links such a page and its original with a language switch.
     29* The page template "Page in easy language" sets pages in easy language (Leichte Sprache) in a narrower column with larger text, line height 1.6, left aligned and without hyphenation.
    3030
    3131These properties are checked by an automated test suite (axe-core and a BITV 2.0 suite with keyboard, layout, contrast and form tests) on every template and pattern in every style variation. Automated tests do not replace a test by people: screen reader checks are done by hand, and the accessibility of a site also depends on its content and plugins. Report accessibility problems at https://leitvia.com.
    … …  
    3737* Templates for the shop page, product categories, tags, attributes and brands (these use the shop template), product search results, single products, cart, checkout and order confirmation. The My account page is created by WooCommerce; the theme styles its login, registration and account forms.
    3838* Template parts "Shop header" with product search, customer account and mini cart, and for the checkout a header with logo and a link back to the cart and a minimal footer, without the main navigation.
    39 * Shop patterns in the category "Shop": shop hero with product, category tiles, new arrivals, bestsellers, a benefits bar, trust badges and "Legal price information". The last one shows the tax note, shipping costs, unit price and delivery time from the blocks of Germanized, is offered only while Germanized is active and is already part of the single product template.
     39* Shop patterns in the category "Shop": shop hero with product, category tiles, new arrivals, bestsellers, a benefits bar, trust badges and "Legal price information". The last one shows the tax note, shipping costs, unit price and delivery time from the blocks of Germanized, is offered only while Germanized is active and is already part of the single product template. "Legal guarantee notice" shows the EU notice on the legal guarantee from Germanized below the add to cart form, as a disclosure with a text summary, the label and a link to europa.eu; the theme renders the notice this way in cart and checkout as well.
    4040* Styles for prices, sale badge, ratings, product tabs, cart, checkout, notices and mini cart come from the same design tokens as the rest of the theme, in every style variation. They load only on pages that use the blocks.
    4141* Plugins that hook into the classic WooCommerce templates keep working: the templates are built like the block templates of WooCommerce, so the classic product, shop and account hooks fire, and the product page uses the classic product tabs and add to cart form.
    … …  
    5252Leitvia itself makes no external requests and sets no cookies. Fonts, images and styles ship with the theme, and templates and patterns show no avatars, because WordPress loads them from Gravatar, a third-party service; author pages identify the author by name and biography. WordPress core, plugins and embedded content can still send requests or set cookies.
    5353
    54 WooCommerce loads nothing from other hosts on the front end of a new shop, but its feature "Order attribution" is on by default and sets cookies (sbjs_*) on every page view, before a visitor does anything. Switch it off under WooCommerce, Settings, Advanced, Features unless your consent solution covers it; the cart cookies then only appear once a visitor adds a product to the cart. Usage tracking and marketplace suggestions in the admin can be switched off under WooCommerce, Settings, Advanced as well. The recipe "Shop" of the plugin Leitvia Studio switches all of these off. Product reviews show avatars through WordPress; without a plugin for local profile pictures they come from Gravatar while "Show Avatars" under Settings, Discussion is on.
     54WooCommerce loads nothing from other hosts on the front end of a new shop, but its feature "Order attribution" is on by default and sets cookies (sbjs_*) on every page view, before a visitor does anything. Switch it off under WooCommerce, Settings, Advanced, Features unless your consent solution covers it; the cart cookies then only appear once a visitor adds a product to the cart. Usage tracking and marketplace suggestions in the admin can be switched off under WooCommerce, Settings, Advanced as well. Product reviews show avatars through WordPress; without a plugin for local profile pictures they come from Gravatar while "Show Avatars" under Settings, Discussion is on.
    5555
    5656== Support ==
    … …  
    6666* Imprint: https://leitvia.com/legal-notice/ (German original: https://leitvia.com/de/impressum/)
    6767* Privacy policy: https://leitvia.com/privacy-policy/
    68 * Terms for the paid Leitvia Pro plans and the account on leitvia.com (they do not apply to this free software): https://leitvia.com/terms/
    6968
    7069== Changelog ==
     70
     71= 1.2.11 =
     72* The description and the readme describe the theme on its own, without recommending plugins or paid add-ons.
     73* The readme quotes the copyright lines of the bundled fonts from their OFL.txt files and lists the origin of every image, logo and icon.
     74* The licence text is LICENSE.txt.
     75* The pattern Footer mega names no translation plugin in its description. Design contract 1.13.3.
     76* The fonts of the active style are preloaded through WordPress (filter wp_preload_resources) instead of link tags the theme prints itself; the files and the order stay the same.
     77* Right-to-left languages: content that templates and patterns align to the start edge sits on the right, as it should, instead of on the left (core writes the left alignment as a physical margin).
     78* Table style Comparison: the first column stays in place while a wide table scrolls sideways, for example under 200 % text zoom, so every row keeps its label and the table shows that it scrolls (WCAG 1.4.4, 1.4.10).
     79
     80= 1.2.10 =
     81* Long words no longer push a page sideways on phones: headings and post titles wrap a word that is longer than the line, and German headings hyphenate (WCAG 1.4.10 Reflow). Pages in easy language keep words whole.
     82
     83= 1.2.9 =
     84* New pattern Video with transcript: a video with poster and caption, followed by a folded transcript with the text of every scene.
     85* Videos: while a control of a video has focus, the video shows the focus ring of the theme. The browser draws the controls itself, out of reach for theme CSS.
     86
     87= 1.2.8 =
     88* Readable type on phones: small meta text is 14 px instead of 13 px, and headings no longer force the finest optical size of a variable font, whose hairlines break up on small screens.
     89
     90= 1.2.7 =
     91* Documentation pages: full-width sections in the content column line up with the page title instead of sitting indented by the page padding.
     92* CSS ships without comments; the code is unchanged and readable.
     93
     94= 1.2.6 =
     95* Pattern "Price list": the source line names a sample price list instead of the theme.
     96
     97= 1.2.5 =
     98* Inverse in dark style variations: the band keeps its dark surface and gets a hairline in the stroke color, so it stands apart from the page. Design contract 1.13.2.
     99* Footer mega and the second card of Compare two use the Inverse style instead of a fixed ink surface, so they stay dark in dark style variations; the social logos of the footer take the text color of the band.
     100
     101= 1.2.4 =
     102* Hero with card over image: the card reaches into the image again and fills the row on wide screens; in 1.2.3 a core rule for columns with a fixed width kept it at its own width beside the image.
     103
     104= 1.2.3 =
     105* New header patterns: Header with button (header-cta) with the main navigation and one button for the main action, Header with service bar (header-utility) with opening hours and phone number in a slim bar above, and Header with centered logo (header-split) with the navigation on the left and the logo exactly in the middle.
     106* New hero patterns: Hero with card over image (hero-overlap), a large photo with the text card reaching into it, and Hero with three teasers (hero-teaser-trio), three tall picture teasers as the entry of a home page.
     107* New block styles: Overlap for Columns, Header split for Group and Header action for Buttons, which hides the header button below 1024 px. Design contract 1.13.1.
     108
     109= 1.2.2 =
     110* Right-to-left: the sale badge on product images sits at the inline start and the product attribute table pads at the inline end, so both mirror in right-to-left languages.
     111
     112= 1.2.1 =
     113* A search placed in the page content, such as the pattern Hero with search, replaces the search of the header on that page, so the front page of a help center shows one search field instead of two.
     114
     115= 1.2.0 =
     116* The EU notice on the legal guarantee of Germanized is a disclosure with a text summary, the label at 20rem and a text link to europa.eu, in every variant and place: product block, cart, checkout, the shortcode and the footer. No popover, no link to "#".
     117* New pattern Legal guarantee notice (shop-legal-guarantee), placed in the single product template below the add to cart form. It registers only with Germanized and shows only while the notice is switched on there.
     118* The footer location of Germanized sits inside the footer landmark, through the new action leitvia_footer_end that other plugins can use as well.
     119* Theme contract 1.13.0.
     120
     121= 1.1.0 =
     122* The theme description and the readme name the free plugin Leitvia Studio and what it adds.
     123* New patterns: Downloads (content-downloads) in the new list style Download, one text link per file with format and size; Masthead (header-masthead) for a newspaper; Hero with search (hero-search) for documentation and help centers; Front page (teaser-front-page) with the sticky lead story and headlines in brief.
     124* Blog: lists of posts get a continue reading link that names the post for screen readers, the blog heading takes title and excerpt of the posts page, and single posts get an author box without avatar, a post navigation that says previous or next article and up to three related posts from the same categories.
     125* Shop category tiles show the image of the category through the new binding source leitvia/term-image, with width and height set on render; a category without an image keeps name and description.
     126* Clear on a variable product is a button instead of a link to "#", so screen readers announce an action and Space presses it.
     127* Button labels wrap between words, the headings of the shop USP bar are level 2.
    71128
    72129= 1.0.2 =
    … …  
    114171= Fonts =
    115172
    116 Bundled locally (latin and latin-ext subsets, WOFF2), all licensed under the SIL Open Font License 1.1. The license text sits next to each font in assets/fonts/. Files were obtained from Google Fonts (https://fonts.google.com), source repository https://github.com/google/fonts.
     173Bundled locally (latin and latin-ext subsets, WOFF2), all licensed under the SIL Open Font License 1.1. The license text with the copyright line below sits next to each font in assets/fonts/<font>/OFL.txt. Files were obtained from Google Fonts (https://fonts.google.com), source repository https://github.com/google/fonts.
    117174
    118 * Newsreader (with the optical size axis), Copyright 2020 The Newsreader Project Authors, SIL OFL 1.1, https://github.com/productiontype/Newsreader
    119 * Inter Tight (upright and italic, weight axis), Copyright 2022 The Inter Project Authors, SIL OFL 1.1, https://github.com/google/fonts/tree/main/ofl/intertight
    120 * IBM Plex Sans (upright and italic, weight axis), Copyright 2017 IBM Corp., SIL OFL 1.1, https://github.com/IBM/plex
    121 * IBM Plex Mono, Copyright 2017 IBM Corp., SIL OFL 1.1, https://github.com/IBM/plex
     175* Newsreader (with the optical size axis): Copyright 2020 The Newsreader Project Authors (http://github.com/productiontype/Newsreader). License: SIL Open Font License 1.1, assets/fonts/newsreader/OFL.txt.
     176* Inter Tight (upright and italic, weight axis): Copyright 2022 The Inter Project Authors (https://github.com/rsms/inter-tight). License: SIL Open Font License 1.1, assets/fonts/inter-tight/OFL.txt.
     177* IBM Plex Sans (upright and italic, weight axis): Copyright © 2017 IBM Corp. with Reserved Font Name "Plex". Source: https://github.com/IBM/plex. License: SIL Open Font License 1.1, assets/fonts/ibm-plex-sans/OFL.txt.
     178* IBM Plex Mono: Copyright © 2017 IBM Corp. with Reserved Font Name "Plex". Source: https://github.com/IBM/plex. License: SIL Open Font License 1.1, assets/fonts/ibm-plex-mono/OFL.txt.
    122179
    123180= Images and logos =
    124181
    125 Images and logos in assets/images are created by Patrick Schlesinger, CMS ADMINS, licensed under GPLv2 or later.
     182All files in assets/images were created by Patrick Schlesinger, CMS ADMINS, for this theme and are licensed under GPLv2 or later:
     183
     184* landscape.webp, portrait.webp, square.webp, detail.webp: placeholder illustrations for the patterns, drawn as vector graphics and exported as WebP.
     185* logo-1.svg to logo-5.svg: logos of fictional companies (Tervane, Kolmar Works, Brinnel and Co, Halvera, Marlow Fenn) for the pattern "Logos"; any resemblance to real brands is unintended.
     186
     187= Icons =
     188
     189* The download icon of the list style "Download" (assets/css/blocks/core--list.css, an inline SVG used as a CSS mask) was drawn for this theme by Patrick Schlesinger, CMS ADMINS, and is licensed under GPLv2 or later.
    126190
    127191= Screenshot =
  • leitvia/1.2.11/style.css

    r355111 r356188  
    88Tested up to: 7.1
    99Requires PHP: 8.2
    10 Version: 1.0.2
     10Version: 1.2.11
    1111License: GNU General Public License v2 or later
    1212License URI: https://www.gnu.org/licenses/gpl-2.0.html
  • leitvia/1.2.11/styles/colors/night.json

    r355111 r356188  
    2626                        "core/cover": {
    2727                                "variations": {
    28                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     28                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    2929                                }
    3030                        },
    3131                        "core/group": {
    3232                                "variations": {
    33                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     33                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    3434                                }
    3535                        }
  • leitvia/1.2.11/styles/corporate-dark.json

    r355111 r356188  
    6868                        "core/cover": {
    6969                                "variations": {
    70                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     70                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    7171                                }
    7272                        },
    7373                        "core/group": {
    7474                                "variations": {
    75                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     75                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    7676                                }
    7777                        }
  • leitvia/1.2.11/styles/swiss-editorial-dark.json

    r355111 r356188  
    6969                        "core/cover": {
    7070                                "variations": {
    71                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     71                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    7272                                }
    7373                        },
    7474                        "core/group": {
    7575                                "variations": {
    76                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     76                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    7777                                }
    7878                        }
  • leitvia/1.2.11/styles/warm-editorial-dark.json

    r355111 r356188  
    2626                        "core/cover": {
    2727                                "variations": {
    28                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     28                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    2929                                }
    3030                        },
    3131                        "core/group": {
    3232                                "variations": {
    33                                         "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" } }
     33                                        "inverse": { "color": { "background": "var:preset|color|surface-alt", "text": "var:preset|color|ink" }, "border": { "color": "var:preset|color|stroke", "style": "solid", "width": "1px" } }
    3434                                }
    3535                        }
  • leitvia/1.2.11/templates/archive.html

    r355111 r356188  
    1414                        <!-- wp:post-title {"isLink":true} /-->
    1515                        <!-- wp:post-excerpt /-->
     16                        <!-- wp:pattern {"slug":"leitvia/hidden-page-read-more"} /-->
    1617                <!-- /wp:post-template -->
    1718                <!-- wp:query-pagination -->
  • leitvia/1.2.11/templates/author.html

    r355111 r356188  
    2020                        <!-- wp:post-title {"isLink":true,"fontSize":"heading-m"} /-->
    2121                        <!-- wp:post-excerpt /-->
     22                        <!-- wp:pattern {"slug":"leitvia/hidden-page-read-more"} /-->
    2223                <!-- /wp:post-template -->
    2324                <!-- wp:query-pagination -->
  • leitvia/1.2.11/templates/home.html

    r355111 r356188  
    1212                        <!-- wp:post-title {"isLink":true} /-->
    1313                        <!-- wp:post-excerpt /-->
     14                        <!-- wp:pattern {"slug":"leitvia/hidden-page-read-more"} /-->
    1415                <!-- /wp:post-template -->
    1516                <!-- wp:query-pagination -->
  • leitvia/1.2.11/templates/search.html

    r355111 r356188  
    1212                        <!-- wp:post-title {"isLink":true} /-->
    1313                        <!-- wp:post-excerpt /-->
     14                        <!-- wp:pattern {"slug":"leitvia/hidden-page-read-more"} /-->
    1415                <!-- /wp:post-template -->
    1516                <!-- wp:query-pagination -->
  • leitvia/1.2.11/templates/single-product.html

    r355111 r356188  
    3636                        <!-- wp:post-excerpt {"excerptLength":100} /-->
    3737                        <!-- wp:woocommerce/add-to-cart-form /-->
     38                        <!-- wp:pattern {"slug":"leitvia/shop-legal-guarantee"} /-->
    3839                        <!-- wp:woocommerce/product-meta -->
    3940                        <div class="wp-block-woocommerce-product-meta">
  • leitvia/1.2.11/templates/single.html

    r355111 r356188  
    1717                <!-- wp:post-featured-image {"aspectRatio":"16/9","align":"wide"} /-->
    1818
    19                 <!-- wp:post-content {"layout":{"type":"constrained","justifyContent":"left"}} /-->
     19                <!-- wp:post-content {"align":"wide","layout":{"type":"constrained","justifyContent":"left"}} /-->
    2020
    2121                <!-- wp:post-terms {"term":"post_tag"} /-->
    … …  
    2828                <hr class="wp-block-separator has-alpha-channel-opacity is-style-wide"/>
    2929                <!-- /wp:separator -->
    30                 <!-- wp:post-navigation-link {"type":"previous","showTitle":true} /-->
    31                 <!-- wp:post-navigation-link {"showTitle":true} /-->
     30                <!-- wp:pattern {"slug":"leitvia/hidden-page-post-author"} /-->
     31                <!-- wp:pattern {"slug":"leitvia/hidden-page-post-navigation"} /-->
     32                <!-- wp:pattern {"slug":"leitvia/hidden-page-related-posts"} /-->
    3233                <!-- wp:comments -->
    3334                <div class="wp-block-comments">
  • leitvia/1.2.11/theme.json

    r355111 r356188  
    3333                        "defaultTextShadowPresets": false,
    3434                        "fontSizes": [
    35                                 { "slug": "meta", "name": "Meta", "size": "0.8125rem", "fluid": false },
     35                                { "slug": "meta", "name": "Meta", "size": "0.875rem", "fluid": false },
    3636                                { "slug": "body", "name": "Body", "size": "1.125rem", "fluid": { "min": "1.0625rem", "max": "1.1875rem" } },
    3737                                { "slug": "lead", "name": "Lead", "size": "1.3125rem", "fluid": { "min": "1.1875rem", "max": "1.375rem" } },
Note: See TracChangeset for help on using the changeset viewer.