/*
Theme Name: Sya Theme
Theme URI:
Author:
Author URI:
Description: A modern agency starter theme built with block editor patterns and theme.json.
Version: 1.4.32
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sya-theme
Tags: block-patterns, block-styles, full-site-editing, wide-blocks
*/

/* ==========================================================================
   Self-hosted fonts (Geom, Vend Sans, Victor Mono) — pulled from Google Fonts'
   gstatic and bundled in assets/fonts/ as latin + latin-ext subsets. No
   third-party CSS request, no render-blocking waterfall.
   Geom and Vend Sans are single-master (one file covers the weight range);
   Victor Mono is the Light (300) italic cut — bumped up from Thin for
   readability on the rose background.
   ========================================================================== */

@font-face {
  font-family: 'Geom';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('assets/fonts/geom-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Geom';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('assets/fonts/geom-latinext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Vend Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('assets/fonts/vend-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Vend Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('assets/fonts/vend-sans-latinext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Victor Mono';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url('assets/fonts/victor-mono-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Victor Mono';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url('assets/fonts/victor-mono-italic-latinext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ==========================================================================
   Layer Declarations
   ========================================================================== */

/*
   Cascade layers ensure predictable specificity. Layers are applied in order:

   1. reset    — Browser resets + box-sizing normalization (in this file)
   2. wpglobal — WordPress global-styles-inline-css output (wrapped via PHP filter)
   3. base     — Global element defaults (in this file)
   4. tokens   — Design system tokens via CSS custom properties (in this file)
   5. header   — Header/navigation component styles (see theme/inc/header.css)
   6. components — Reusable component styles (see theme/inc/blocks.css)
   7. utilities — Helper & utility classes (in this file)
   8. overrides — High-specificity fixes (see theme/inc/overrides.css or theme.json)

   Note: Unlayered CSS (styles/blocks/*.css) sits above all layers per the CSS spec.
   Note: Only reset, base, tokens, and utilities are in this file.
   Component-specific CSS is in separate modular files under theme/inc/.
*/

@layer reset, wpglobal, base, tokens, header, components, utilities, overrides;

/* ==========================================================================
   Reset
   ========================================================================== */

@layer reset {
  /* 1. Use a more-intuitive box-sizing model + 2. Remove default margin */
  * {
    box-sizing: border-box;

    &::before,
    &::after {
      box-sizing: border-box;
    }

    &:not(dialog) {
      margin: 0;
    }
  }

  /* 3. Enable keyword animations + 4. Accessible line-height + 5. Text rendering */
  html {
    @media (prefers-reduced-motion: no-preference) {
      interpolate-size: allow-keywords;
    }
  }

  body {
    line-height: var(--wp--custom--line-height--normal, 1.5);
    -webkit-font-smoothing: antialiased;
  }

  /* 6. Improve media defaults */
  :is(img, picture, video, canvas, svg) {
    display: block;
    max-inline-size: 100%;
  }

  /* 7. Inherit fonts for form controls */
  :is(input, button, textarea, select) {
    font: inherit;
  }

  /* 8. Avoid text overflows + 9. Improve line wrapping */
  :is(p, h1, h2, h3, h4, h5, h6) {
    overflow-wrap: break-word;
  }

  p {
    text-wrap: pretty;
  }

  :is(h1, h2, h3, h4, h5, h6) {
    text-wrap: balance;
  }

  /* 10. Create a root stacking context */
  :is(#root, #__next) {
    isolation: isolate;
  }
}

/* ==========================================================================
   Base
   ========================================================================== */

@layer base {
  :where(a) {
    color: inherit;
  }

  :where(ul, ol) {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  /*
   * Editorial post-content rhythm. WordPress emits no flow block-gap for
   * core/post-content here, so the theme owns the vertical spacing. List
   * markers + indent are restored too (the :where reset above strips them from
   * all lists for UI/nav use). All layered — no unlayered rules needed now the
   * global `main *` reset is gone; @layer base beats @layer reset's margin:0.
   */
  .entry-content > * + * {
    margin-block-start: var(--wp--preset--spacing--40);
  }
  .entry-content > :is(h2, h3, h4) {
    margin-block-start: var(--wp--preset--spacing--60);
  }
  .entry-content > :first-child {
    margin-block-start: 0;
  }
  .entry-content :is(ul, ol) {
    list-style: revert;
    padding-inline-start: 1.5rem;
  }
  .entry-content li + li {
    margin-block-start: 0.35em;
  }

  /* Skip link — visible on focus only */
  .skip-link {
    position: absolute;
    inset-inline-start: -9999px;
    z-index: var(--wp--custom--z-index--toast, 400);
    padding-block: 0.5em;
    padding-inline: 1em;
    background: var(--wp--preset--color--contrast, #0f172a);
    color: var(--wp--preset--color--base, #fff);
    text-decoration: none;
    font-weight: 700;

    &:focus {
      inset-inline-start: 0;
      inset-block-start: 0;
    }
  }
}

/* ==========================================================================
   Tokens — Derived colors & semantic aliases via CSS Relative Colors (RCS)
   All values here are derived from theme.json palette entries using oklch()
   relative color syntax. Swapping hex values in theme.json auto-propagates.
   ========================================================================== */

/*
   QUICK REFERENCE — CSS Custom Properties (All Sources)
   ================================================

   COLOR PALETTE (from theme.json)
   —— Preset colors (use in blocks):
   --wp--preset--color--{primary, accent, secondary, base, contrast, subtle, muted}

   —— Derived states (hover, active, subtle, alpha scales):
   --color-{primary,accent,secondary}-hover           (lighten +15%)
   --color-{primary,accent,secondary}-active          (darken -15%)
   --color-{primary,accent}-subtle                    (light tint, 50% alpha)
   --color-{primary,accent,base,contrast}-alpha-{10,20,50,80}  (transparency scales)

   —— Status colors (contextual messages):
   --color-{success,warning,error,info}              (main color)
   --color-{success,warning,error,info}-subtle       (light variant)

   SEMANTIC SURFACES
   --color-surface                 (card backgrounds)
   --color-surface-raised          (slightly elevated)
   --color-surface-overlay         (semi-transparent overlay)
   --color-surface-sunken          (indented area)
   --color-surface-scrim           (semi-transparent dark layer)

   BORDERS & FOCUS
   --color-border                  (subtle dividers)
   --color-border-strong           (prominent dividers)
   --color-border-interactive      (interactive elements)
   --focus-ring                    (2px solid primary color)
   --focus-ring-offset             (2px)

   Z-INDEX (from theme.json — keep minimal)
   --wp--custom--z-index--sticky   (200 — header)
   --wp--custom--z-index--dropdown (300 — menus)
   --wp--custom--z-index--overlay  (250 — overlays)
   --wp--custom--z-index--modal    (300 — modals)
   --wp--custom--z-index--toast    (400 — notifications)

   TRANSITIONS (from theme.json — use timing + easing separately for flexibility)
   --wp--custom--transition--fast  (150ms ease — shorthand, use for simple transitions)
   --wp--custom--transition--normal (300ms ease — shorthand, use for simple transitions)
   --wp--custom--transition--slow  (500ms ease — shorthand, use for simple transitions)

   TIMING (compose with easing for complex multi-property transitions)
   --wp--custom--timing--fast      (150ms)
   --wp--custom--timing--normal    (300ms)
   --wp--custom--timing--slow      (500ms)

   EASING (use with timing for granular control)
   --wp--custom--easing--standard  (ease — standard, smooth)
   --wp--custom--easing--in        (ease-in — slow start)
   --wp--custom--easing--out       (ease-out — slow end)
   --wp--custom--easing--inOut     (cubic-bezier custom — smooth both ends)

   TYPOGRAPHY (from theme.json)
   --wp--preset--font-family--{heading, body}
   --wp--preset--font-size--{small, medium, large, x-large, 2x-large, 3x-large, 4x-large}
   --wp--custom--line-height--{tight, normal, relaxed}
   --wp--custom--letter-spacing--{tight, normal, wide}

   SPACING (from theme.json, increments 10–100)
   --wp--preset--spacing--{10, 20, 30, 40, 50, 60, 70, 80, 90, 100}

   SHADOWS (from theme.json)
   --wp--preset--shadow--{sm, md, lg, xl, inner}

   BORDER RADIUS (from theme.json)
   --wp--preset--border--radius--{small, medium, large, full}

   LAYOUT (from theme.json)
   --wp--style--global--content-size  (800px — main content width)
   --wp--style--global--wide-size     (1200px — wide section width)

   Note: WordPress preset variables are auto-generated from theme.json.
   Custom theme variables (--wp--custom--*) are defined in theme.json settings.custom.
*/

@layer tokens {
  :root {
    /* ----- Primary: hover / active / subtle ----- */
    --color-primary-hover: oklch(
      from var(--wp--preset--color--primary) calc(l + 0.15) c h
    );
    --color-primary-active: oklch(
      from var(--wp--preset--color--primary) calc(l - 0.15) c h
    );
    --color-primary-subtle: oklch(
      from var(--wp--preset--color--primary) calc(l + 0.45) c h / 0.5
    );

    /* ----- Accent: hover / active / subtle ----- */
    --color-accent-hover: oklch(
      from var(--wp--preset--color--accent) calc(l + 0.15) c h
    );
    --color-accent-active: oklch(
      from var(--wp--preset--color--accent) calc(l - 0.15) c h
    );
    --color-accent-subtle: oklch(
      from var(--wp--preset--color--accent) calc(l + 0.45) c h / 0.5
    );

    /* ----- Secondary: hover ----- */
    --color-secondary-hover: oklch(
      from var(--wp--preset--color--secondary) calc(l + 0.15) c h
    );

    /* ----- Primary: transparency scale ----- */
    --color-primary-alpha-10: oklch(
      from var(--wp--preset--color--primary) l c h / 0.1
    );
    --color-primary-alpha-20: oklch(
      from var(--wp--preset--color--primary) l c h / 0.2
    );
    --color-primary-alpha-50: oklch(
      from var(--wp--preset--color--primary) l c h / 0.5
    );

    /* ----- Accent: transparency scale ----- */
    --color-accent-alpha-10: oklch(
      from var(--wp--preset--color--accent) l c h / 0.1
    );
    --color-accent-alpha-20: oklch(
      from var(--wp--preset--color--accent) l c h / 0.2
    );
    --color-accent-alpha-50: oklch(
      from var(--wp--preset--color--accent) l c h / 0.5
    );

    /* ----- Contrast: transparency scale (overlays, borders, scrims) ----- */
    --color-contrast-alpha-5: oklch(
      from var(--wp--preset--color--contrast) l c h / 0.05
    );
    --color-contrast-alpha-10: oklch(
      from var(--wp--preset--color--contrast) l c h / 0.1
    );
    --color-contrast-alpha-20: oklch(
      from var(--wp--preset--color--contrast) l c h / 0.2
    );
    --color-contrast-alpha-50: oklch(
      from var(--wp--preset--color--contrast) l c h / 0.5
    );
    --color-contrast-alpha-80: oklch(
      from var(--wp--preset--color--contrast) l c h / 0.8
    );

    /* ----- Base: transparency scale (light overlays on dark bgs) ----- */
    --color-base-alpha-10: oklch(
      from var(--wp--preset--color--base) l c h / 0.1
    );
    --color-base-alpha-20: oklch(
      from var(--wp--preset--color--base) l c h / 0.2
    );
    --color-base-alpha-50: oklch(
      from var(--wp--preset--color--base) l c h / 0.5
    );

    /* ----- Semantic: surfaces ----- */
    --color-surface: var(--wp--preset--color--base);
    --color-surface-raised: var(--wp--preset--color--subtle);
    --color-surface-overlay: oklch(
      from var(--wp--preset--color--contrast) calc(l - 0.02) c h / 0.97
    );
    --color-surface-sunken: oklch(
      from var(--wp--preset--color--contrast) calc(l - 0.04) c h / 0.94
    );
    --color-surface-scrim: var(--color-contrast-alpha-50);

    /* ----- Semantic: borders ----- */
    --color-border: var(--color-contrast-alpha-10);
    --color-border-strong: var(--color-contrast-alpha-20);
    --color-border-interactive: var(--wp--preset--color--primary);
    --color-border-focus: var(--wp--preset--color--primary);

    /* ----- Semantic: focus ring ----- */
    --color-focus-ring: var(--wp--preset--color--primary);
    --focus-ring: 2px solid var(--color-focus-ring);
    --focus-ring-offset: 2px;

    /* ----- Status: hex fallbacks (overridden to OKLCH below) ----- */
    --color-success: #16a34a;
    --color-warning: #ca8a04;
    --color-error: #dc2626;
    --color-info: #2563eb;
  }

  /* OKLCH enhancement for status colors + derive subtle variants via relative colors */
  @supports (color: oklch(0% 0 0)) {
    :root {
      --color-success: oklch(55% 0.18 150);
      --color-success-subtle: oklch(
        from var(--color-success) calc(l + 0.42) c h
      );
      --color-warning: oklch(70% 0.16 85);
      --color-warning-subtle: oklch(
        from var(--color-warning) calc(l + 0.27) c h
      );
      --color-error: oklch(55% 0.22 28);
      --color-error-subtle: oklch(from var(--color-error) calc(l + 0.42) c h);
      --color-info: oklch(55% 0.2 260);
      --color-info-subtle: oklch(from var(--color-info) calc(l + 0.42) c h);
    }
  }
}

/* ==========================================================================
   Utilities
   ========================================================================== */

@layer utilities {
  /* Constrain wide-aligned blocks */
  .alignwide {
    max-inline-size: var(--wp--style--global--wide-size, 1200px);
    margin-inline: auto;
  }

  /* Post title respects parent container width */
  .wp-block-post-title {
    max-inline-size: 100%;
  }

  /* Visually hidden but accessible to screen readers */
  .screen-reader-text {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* Text color utilities mapped to token scale */
  .has-muted-text {
    color: var(--wp--preset--color--muted, #64748b);
  }

  .has-success-text {
    color: var(--color-success, #16a34a);
  }

  .has-warning-text {
    color: var(--color-warning, #ca8a04);
  }

  .has-error-text {
    color: var(--color-error, #dc2626);
  }

  /* Raised surface with shadow */
  .has-raised-surface {
    background: var(--color-surface, #fff);
    box-shadow: var(--wp--preset--shadow--md);
    border-radius: var(--wp--preset--border--radius--medium, 0.5rem);
  }

  /* Horizontal scroll-snap container — reusable, not koulutus-specific */
  .sya-scroll-snap {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    touch-action: pan-x;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: var(--wp--preset--spacing--50);

    &::-webkit-scrollbar {
      display: none;
    }

    & > * {
      scroll-snap-align: start;
      flex-shrink: 0;
    }
  }
}

@layer components {
  /*
   * Training calendar card sizing.
   * 72vw ≈ card fills ~72% of viewport → ~1.4 cards visible at any time.
   * Clamp keeps cards readable on large viewports.
   * Adjust the vw value visually after first render if needed.
   */
  .sya-pattern-bg .sya-event-card {
    /* Fixed width (not just min-width) so long card text wraps instead of
       stretching the flex item — keeps cards uniform and the meta grid intact. */
    width: clamp(260px, 72vw, 360px);
  }

  /*
   * Heading "slide" (opener) — narrower than the cards so the first card always
   * peeks past it, signalling the carousel scrolls. (Block emits .sya-training-intro;
   * the old hand-built version used a .wp-block-html wrapper.)
   */
  .sya-pattern-bg .sya-training-intro {
    width: clamp(220px, 60vw, 320px);
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--40);
  }

  /*
   * Full-bleed carousel: the scroll row spans the rose band edge-to-edge.
   * Left gutter aligns the intro + first card with the page's wide content
   * (1200px), then collapses to the root gutter on narrow viewports via max().
   * Cards bleed off the right edge to signal "more — scroll right".
   * scroll-padding-inline-start makes snapped cards land flush on the gutter.
   */
  .sya-carousel-wrapper {
    --sya-carousel-gutter: max(
      var(--wp--style--root--padding-left, var(--wp--preset--spacing--40)),
      calc((100% - var(--wp--style--global--wide-size, 1200px)) / 2)
    );
  }

  .sya-pattern-bg .sya-scroll-snap {
    padding-inline-start: var(--sya-carousel-gutter);
    padding-inline-end: var(--wp--preset--spacing--40);
    scroll-padding-inline-start: var(--sya-carousel-gutter);
  }

  /* Prev/next buttons — below the carousel, right-aligned to the gutter.
     (Top margin is set unlayered below — the `main *` reset would zero it here.) */
  .sya-carousel-nav {
    display: flex;
    justify-content: flex-end;
    gap: var(--wp--preset--spacing--20);
    margin-block-start: var(--wp--preset--spacing--60);
    padding-inline: var(--sya-carousel-gutter);
  }

  .sya-carousel-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    border: 1.5px solid var(--wp--preset--color--base);
    background: transparent;
    color: var(--wp--preset--color--base);
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    transition: background 0.15s;

    &:hover:not(:disabled) {
      background: color-mix(in oklch, var(--wp--preset--color--base) 15%, transparent);
    }

    &:focus-visible {
      outline: 2px solid var(--wp--preset--color--base);
      outline-offset: 2px;
    }

    &:disabled {
      opacity: 0.3;
      cursor: default;
    }
  }

  /* ----------------------------------------------------------------------
   * Editorial hero — full-bleed band on single-koulutus / single-kirja /
   * single-henkilo. Pattern-weave bg over primary, cream display type.
   * Curved bottom (.sya-hero-curved) clips the band into a soft arch.
   * The back-link replaces the eyebrow position; pre-existing
   * .sya-hero-curved overrides in @layer overrides handle the clip-path.
   * -------------------------------------------------------------------- */
  .sya-hero {
    position: relative;
    isolation: isolate;
    /* Generous top padding so the fixed header doesn't crowd the back-link.
       Bottom padding is bigger when curved so the clip doesn't bite into
       the title — handled below in .sya-hero-curved. */
    padding-block-start: clamp(7rem, 14vw, 10rem);
    padding-block-end: clamp(3.5rem, 9vw, 6rem);
    padding-inline: var(--wp--preset--spacing--40);
  }

  /* Curved variant — needs more bottom padding so the ellipse clip
     doesn't slice into the title or role. */
  .sya-hero-curved.sya-hero {
    padding-block-end: clamp(5rem, 12vw, 8rem);
  }

  .sya-hero__inner {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--wp--preset--spacing--20);
    max-inline-size: 24ch;
  }

  /* Override post-title block defaults inside the hero */
  .sya-hero .wp-block-post-title.sya-hero__title,
  .sya-hero__title {
    font-family: var(--wp--preset--font-family--heading);
    font-size: clamp(2.25rem, 6vw, 4.5rem);
    line-height: 1.04;
    letter-spacing: -0.012em;
    color: var(--wp--preset--color--base);
    margin: 0;
    text-wrap: balance;
    font-weight: 700;
    max-inline-size: 18ch;
  }

  /* Henkilö role displayed inline in the hero — italic body, soft cream */
  .sya-hero .sya-henkilo-role {
    font-family: var(--wp--preset--font-family--body);
    font-style: italic;
    font-size: clamp(1.05rem, 1.4vw, 1.25rem);
    color: color-mix(in oklch, var(--wp--preset--color--base) 88%, transparent);
    margin: var(--wp--preset--spacing--20) 0 0;
    padding: 0;
    border: 0;
  }

  /* Back-link inside hero is the new "eyebrow". Body font (Vend Sans)
     italic at a heavier weight reads much better on the dusty-rose
     pattern bg than the original Victor Mono Thin Italic — that
     accent face is too thin for inverse text on textured background. */
  .sya-hero .sya-back-link {
    font-family: var(--wp--preset--font-family--body);
    font-style: italic;
    font-weight: 600;
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: color-mix(in oklch, var(--wp--preset--color--base) 92%, transparent);
    margin-block-end: var(--wp--preset--spacing--30);
  }

  .sya-hero .sya-back-link:hover,
  .sya-hero .sya-back-link:focus-visible {
    color: var(--wp--preset--color--base);
  }

  /* Body wrapper below the hero — restores breathing room before footer.
     Inline padding here (instead of on main) so alignfull children
     of main can break out edge-to-edge without 16px gutters from
     has-global-padding. */
  .sya-single-body {
    padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--80);
    padding-inline: var(--wp--preset--spacing--40);
  }

  /* Strip the root-padding gutter from <main> on the single templates —
     the hero, kalenteri, and other alignfull sections need to span
     edge-to-edge. Inner wrappers (.sya-single-body, the kalenteri's
     own .alignwide carousel) provide their own inline padding. */
  main#main-content:has(> .sya-hero) {
    padding-inline: 0;
  }

  /* ----------------------------------------------------------------------
   * Single-view layout — two-column grid for single-koulutus / single-kirja.
   * Main column flexes; sidebar is sticky on desktop.
   * BEM child selectors kept flat (native CSS nesting silently drops &__).
   * -------------------------------------------------------------------- */
  .sya-single-layout {
    display: grid;
    gap: var(--wp--preset--spacing--50);
  }

  .sya-single-layout__main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--50);
  }

  .sya-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--40);
  }

  /* Title sits full-width above the grid (newspaper-headline style) */
  .sya-single-layout__title {
    margin-block-end: var(--wp--preset--spacing--40);
  }

  @media (min-width: 960px) {
    .sya-single-layout {
      grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
      gap: var(--wp--preset--spacing--70);
      align-items: start;
    }

    /* Sidebar is DOM-first (so it stacks above main on mobile) but
       grid placement puts it visually in the right column on desktop.
       Main column explicitly assigned to column 1 to match. */
    .sya-sidebar {
      grid-column: 2;
      grid-row: 1;
      position: sticky;
      /* Clear the fixed 72px header (+ gap) so the sticky sidebar doesn't
         slide under it. TODO: swap 72px for a header-height token in the #1
         header refactor. */
      inset-block-start: calc(72px + var(--wp--preset--spacing--40));
    }

    .sya-single-layout__main {
      grid-column: 1;
      grid-row: 1;
    }
  }

  /* Back-arrow link: arrow nudges left on hover */
  .sya-back-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--small);
    font-weight: 500;
    text-decoration: none;
    color: var(--wp--preset--color--contrast);
    letter-spacing: 0.02em;
    transition: color 0.15s ease;
  }

  .sya-back-link:hover,
  .sya-back-link:focus-visible {
    color: var(--wp--preset--color--primary);
  }

  .sya-back-link__arrow {
    display: inline-block;
    transition: transform 0.18s ease;
  }

  .sya-back-link:hover .sya-back-link__arrow,
  .sya-back-link:focus-visible .sya-back-link__arrow {
    transform: translateX(-3px);
  }

  /* Sidebar meta cards (refines the bare dl from koulutus_meta / kirja_meta) */
  .sya-sidebar .koulutus-meta,
  .sya-sidebar .kirja-meta {
    background: color-mix(in oklch, var(--wp--preset--color--contrast) 4%, var(--wp--preset--color--base));
    border-block-start: 2px solid var(--wp--preset--color--primary);
    padding: var(--wp--preset--spacing--40);
    margin: 0;
  }

  .sya-sidebar .koulutus-meta dl,
  .sya-sidebar .kirja-meta dl {
    margin: 0;
    display: grid;
    gap: var(--wp--preset--spacing--30);
  }

  .sya-sidebar .koulutus-meta__row,
  .sya-sidebar .kirja-meta__row {
    display: grid;
    gap: 0.2em;
  }

  .sya-sidebar .koulutus-meta dt,
  .sya-sidebar .kirja-meta dt {
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 65%, transparent);
    font-weight: 600;
    margin: 0;
  }

  .sya-sidebar .koulutus-meta dd,
  .sya-sidebar .kirja-meta dd {
    font-family: var(--wp--preset--font-family--body);
    font-size: 1rem;
    color: var(--wp--preset--color--contrast);
    margin: 0;
    font-weight: 500;
  }

  /* Sticky CTA button — full sidebar width, brand pink */
  .sya-anchor-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4em;
    padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
    background: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--base);
    text-decoration: none;
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    font-size: 1rem;
    letter-spacing: 0.02em;
    border-radius: 0.25rem;
    transition: background 0.15s ease, transform 0.15s ease;
  }

  .sya-anchor-cta:hover {
    background: color-mix(in oklch, var(--wp--preset--color--primary) 85%, black);
  }

  .sya-anchor-cta:focus-visible {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 3px;
  }

  .sya-anchor-cta__arrow {
    display: inline-block;
    transition: transform 0.18s ease;
  }

  .sya-anchor-cta:hover .sya-anchor-cta__arrow {
    transform: translateY(2px);
  }

  /* Trainers section — small horizontal cards above the form */
  .sya-trainers {
    margin-block-start: var(--wp--preset--spacing--60);
  }

  .sya-trainers__heading {
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--large);
    margin: 0 0 var(--wp--preset--spacing--40);
  }

  .sya-trainers__list {
    display: grid;
    gap: var(--wp--preset--spacing--30);
    grid-template-columns: 1fr;
  }

  @media (min-width: 600px) {
    .sya-trainers__list {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  /* <article> root + stretched <a>::before overlay so wpautop can't
     break the card by inserting <p> tags between block-level children
     of an <a>. Single tab stop, full card click target. */
  .sya-trainer-card {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--wp--preset--spacing--30);
    align-items: center;
    padding: var(--wp--preset--spacing--30);
    border: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 12%, transparent);
    background: var(--wp--preset--color--base);
    color: var(--wp--preset--color--contrast);
    transition: border-color 0.15s ease, transform 0.15s ease;
  }

  .sya-trainer-card:hover,
  .sya-trainer-card:focus-within {
    border-color: var(--wp--preset--color--primary);
    transform: translateY(-2px);
  }

  .sya-trainer-card__photo {
    inline-size: 64px;
    block-size: 64px;
    border-radius: 50%;
    object-fit: cover;
    object-position: top;
    display: block;
  }

  .sya-trainer-card__photo--placeholder {
    background: color-mix(in oklch, var(--wp--preset--color--contrast) 10%, var(--wp--preset--color--base));
  }

  .sya-trainer-card__text {
    display: flex;
    flex-direction: column;
    gap: 0.15em;
    min-inline-size: 0;
  }

  /* Stretched link covers the whole card via ::before overlay */
  .sya-trainer-card__link {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
  }

  .sya-trainer-card__link::before {
    content: "";
    position: absolute;
    inset: 0;
  }

  .sya-trainer-card__link:focus-visible {
    outline: var(--focus-ring);
    outline-offset: 2px;
  }

  /* External trainer name — matches link styling for visual consistency */
  .sya-trainer-card__name {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    color: var(--wp--preset--color--contrast);
  }

  .sya-trainer-card__role {
    font-size: 0.875rem;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 70%, transparent);
  }

  /* Upcoming koulutukset — full-width section, 3-card grid */
  .sya-upcoming {
    margin-block-start: var(--wp--preset--spacing--80);
    padding-block: var(--wp--preset--spacing--70);
    border-block-start: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 10%, transparent);
  }

  .sya-upcoming__heading {
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--large);
    margin: 0 0 var(--wp--preset--spacing--50);
    text-align: center;
  }

  .sya-upcoming__list {
    display: grid;
    gap: var(--wp--preset--spacing--40);
    grid-template-columns: 1fr;
  }

  @media (min-width: 720px) {
    .sya-upcoming__list {
      grid-template-columns: repeat(3, 1fr);
    }
  }

  .sya-upcoming-card {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--20);
    padding: var(--wp--preset--spacing--40);
    background: var(--wp--preset--color--base);
    border: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 12%, transparent);
    text-decoration: none;
    color: var(--wp--preset--color--contrast);
    transition: transform 0.15s ease, border-color 0.15s ease;
  }

  .sya-upcoming-card:hover {
    transform: translateY(-3px);
    border-color: var(--wp--preset--color--primary);
  }

  .sya-upcoming-card__title {
    font-family: var(--wp--preset--font-family--heading);
    font-size: 1.125rem;
    margin: 0;
  }

  .sya-upcoming-card__meta {
    font-size: 0.875rem;
    margin: 0;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 80%, transparent);
  }

  .sya-upcoming-card__label {
    font-family: var(--wp--preset--font-family--heading);
    text-transform: uppercase;
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 65%, transparent);
    margin-inline-end: 0.4em;
    font-weight: 600;
  }

  .sya-upcoming-card__cta {
    margin-block-start: auto;
    padding-block-start: var(--wp--preset--spacing--20);
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    color: var(--wp--preset--color--primary);
    font-size: 0.875rem;
  }

  /* Order form section + checkbox list */
  .sya-order-form {
    margin-block-start: var(--wp--preset--spacing--80);
    padding-block: var(--wp--preset--spacing--70);
    border-block-start: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 10%, transparent);
    scroll-margin-block-start: var(--wp--preset--spacing--50);
  }

  .sya-order-form__heading {
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--large);
    margin: 0 0 var(--wp--preset--spacing--30);
  }

  .sya-order-form__intro {
    margin-block-end: var(--wp--preset--spacing--40);
    max-inline-size: 60ch;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 80%, transparent);
  }

  .sya-checklist {
    display: grid;
    gap: 0.4em;
    padding: var(--wp--preset--spacing--40);
    background: color-mix(in oklch, var(--wp--preset--color--contrast) 3%, var(--wp--preset--color--base));
    border: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 12%, transparent);
    margin-block-end: var(--wp--preset--spacing--40);
  }

  .sya-checklist-item {
    display: flex;
    align-items: flex-start;
    gap: 0.6em;
    cursor: pointer;
    padding: 0.3em 0;
    line-height: 1.4;
  }

  .sya-checklist-item input[type="checkbox"] {
    margin-block-start: 0.2em;
    accent-color: var(--wp--preset--color--primary);
    flex-shrink: 0;
  }

  .sya-checklist-item:hover {
    color: var(--wp--preset--color--primary);
  }

  /* Koulutus form section — mirrors .sya-order-form structure */
  .sya-koulutus-form {
    margin-block-start: var(--wp--preset--spacing--60);
    padding-block-start: var(--wp--preset--spacing--50);
    border-block-start: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 10%, transparent);
    scroll-margin-block-start: var(--wp--preset--spacing--50);
  }

  .sya-koulutus-form__heading {
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--large);
    margin: 0 0 var(--wp--preset--spacing--40);
  }

  /* Anchor scroll-margin for jump targets */
  #ilmoittaudu,
  #tilaa {
    scroll-margin-block-start: var(--wp--preset--spacing--50);
  }

  /* Strong dropcap — opt-in via Gutenberg paragraph "drop cap" toggle */
  p.has-drop-cap:not(:focus)::first-letter {
    float: inline-start;
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    font-size: 4em;
    line-height: 0.85;
    color: var(--wp--preset--color--primary);
    margin-inline-end: 0.08em;
    margin-block-start: 0.05em;
  }

  /* Pull-quote — left bar in primary, italic, breathing room */
  .wp-block-pullquote {
    border: none;
    border-inline-start: 4px solid var(--wp--preset--color--primary);
    padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
    margin-block: var(--wp--preset--spacing--60);
    background: color-mix(in oklch, var(--wp--preset--color--primary) 5%, var(--wp--preset--color--base));
    text-align: start;
  }

  .wp-block-pullquote blockquote {
    margin: 0;
  }

  .wp-block-pullquote p {
    font-family: var(--wp--preset--font-family--body);
    font-style: italic;
    font-size: var(--wp--preset--font-size--large);
    line-height: 1.4;
    color: var(--wp--preset--color--contrast);
    margin: 0;
  }

  .wp-block-pullquote cite {
    display: block;
    margin-block-start: 0.75em;
    font-size: 0.875rem;
    font-style: normal;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 65%, transparent);
  }

  /* Henkilöstö grid — used on /asiantuntijat/ via [henkilosto_grid].
     Simple framed portraits + bio + read-more link. */
  .sya-henkilo-grid {
    margin-block: var(--wp--preset--spacing--70);
    text-align: start;
  }

  .sya-henkilo-grid__heading {
    font-family: var(--wp--preset--font-family--heading);
    font-size: var(--wp--preset--font-size--x-large);
    text-align: center;
    margin: 0 0 var(--wp--preset--spacing--60);
  }

  .sya-henkilo-grid__list {
    display: grid;
    gap: var(--wp--preset--spacing--60) var(--wp--preset--spacing--50);
    grid-template-columns: 1fr;
    max-inline-size: var(--wp--style--global--wide-size, 1200px);
    margin-inline: auto;
    padding-inline: var(--wp--preset--spacing--40);
  }

  @media (min-width: 600px) {
    .sya-henkilo-grid__list {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  @media (min-width: 960px) {
    .sya-henkilo-grid__list {
      grid-template-columns: repeat(3, 1fr);
    }
  }

  .sya-henkilo-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--wp--preset--spacing--20);
    text-align: center;
  }

  .sya-henkilo-card__photo-link {
    display: inline-block;
    margin-block-end: var(--wp--preset--spacing--30);
    border-radius: 50%;
    overflow: clip;
    transition: transform 0.25s ease;
  }

  .sya-henkilo-card__photo {
    inline-size: 200px;
    block-size: 200px;
    border-radius: 50%;
    object-fit: cover;
    object-position: top;
    display: block;
  }

  .sya-henkilo-card__photo--placeholder {
    background: color-mix(in oklch, var(--wp--preset--color--contrast) 10%, var(--wp--preset--color--base));
  }

  .sya-henkilo-card:hover .sya-henkilo-card__photo-link {
    transform: scale(1.03);
  }

  .sya-henkilo-card__name {
    font-family: var(--wp--preset--font-family--heading);
    font-size: 1.25rem;
    line-height: 1.2;
    margin: 0;
  }

  .sya-henkilo-card__name a {
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
  }

  .sya-henkilo-card__name a:hover,
  .sya-henkilo-card__name a:focus-visible {
    color: var(--wp--preset--color--primary);
  }

  .sya-henkilo-card__role {
    font-style: italic;
    color: var(--wp--preset--color--primary);
    font-size: 0.95rem;
    margin: 0;
  }

  .sya-henkilo-card__bio {
    font-family: var(--wp--preset--font-family--body);
    font-size: 0.95rem;
    line-height: 1.55;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 88%, transparent);
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 5;
    line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-align: start;
  }

  .sya-henkilo-card__more {
    font-family: var(--wp--preset--font-family--heading);
    font-weight: 700;
    color: var(--wp--preset--color--primary);
    text-decoration: none;
    font-size: 0.9rem;
    margin-block-start: var(--wp--preset--spacing--20);
  }

  .sya-henkilo-card__more:hover,
  .sya-henkilo-card__more:focus-visible {
    text-decoration: underline;
  }

  @media (prefers-reduced-motion: reduce) {
    .sya-henkilo-card__photo-link {
      transition: none;
    }
    .sya-henkilo-card:hover .sya-henkilo-card__photo-link {
      transform: none;
    }
  }

  /* Single henkilo (personnel) — 2-col body layout.
     Photo on the left, content on the right. Constrained to a sane
     reading width but not too narrow. Stacks on mobile. */
  .sya-henkilo-single {
    padding-block: var(--wp--preset--spacing--70) var(--wp--preset--spacing--80);
    padding-inline: var(--wp--preset--spacing--40);
  }

  .sya-henkilo-single__layout {
    display: grid;
    gap: var(--wp--preset--spacing--60);
    grid-template-columns: 1fr;
    max-inline-size: 70rem;
    margin-inline: auto;
    align-items: start;
  }

  @media (min-width: 768px) {
    .sya-henkilo-single__layout {
      grid-template-columns: minmax(220px, 280px) minmax(0, 1fr);
      gap: var(--wp--preset--spacing--70);
    }
  }

  /* Photo: framed circle, square aspect-ratio so the natural image
     ratio doesn't oval it. */
  .sya-henkilo-single__photo,
  .sya-henkilo-single .wp-block-post-featured-image {
    inline-size: 100%;
    max-inline-size: 280px;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    overflow: clip;
    border: 5px solid var(--wp--preset--color--base);
    outline: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 18%, transparent);
    outline-offset: -5px;
    box-shadow:
      0 16px 32px color-mix(in oklch, var(--wp--preset--color--contrast) 18%, transparent),
      0 3px 6px color-mix(in oklch, var(--wp--preset--color--contrast) 8%, transparent);
    margin: 0 auto;
  }

  .sya-henkilo-single__content {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--40);
  }

  .sya-henkilo-single .wp-block-post-content {
    font-size: 1.0625rem;
    line-height: 1.65;
  }

  .sya-henkilo-role {
    font-style: italic;
    font-size: 1.125rem;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 70%, transparent);
    margin: var(--wp--preset--spacing--20) 0 var(--wp--preset--spacing--50);
  }

  .sya-henkilo-contact {
    margin-block-start: var(--wp--preset--spacing--60);
    padding-block: var(--wp--preset--spacing--40);
    border-block: 1px solid color-mix(in oklch, var(--wp--preset--color--contrast) 12%, transparent);
    text-align: start;
  }

  .sya-henkilo-contact dl {
    display: grid;
    gap: var(--wp--preset--spacing--30);
    margin: 0;
  }

  .sya-henkilo-contact__row {
    display: grid;
    gap: 0.2em;
  }

  .sya-henkilo-contact dt {
    font-family: var(--wp--preset--font-family--heading);
    font-size: 0.7rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: color-mix(in oklch, var(--wp--preset--color--contrast) 65%, transparent);
    font-weight: 600;
  }

  .sya-henkilo-contact dd {
    margin: 0;
  }

  .sya-henkilo-contact a {
    color: var(--wp--preset--color--primary);
  }

  /* Footer text links inherit the cream (base) footer text color so they stay
     legible on the rose background. Social-link icon anchors are excluded —
     they're colored by the core social block. */
  footer.sya-pattern-bg a:not(.wp-block-social-link-anchor) {
    color: inherit;
    text-underline-offset: 0.15em;
  }

  /* Category cards (#46 Koulutustarjontamme) — clickable icon cards. The whole
     card is one link via the stretched heading anchor; the grid itself is
     unlayered (see bottom of file) because WP layout CSS would beat it. */
  .sya-cat-card {
    position: relative;
    background-color: var(--wp--preset--color--subtle);
    border-radius: 2rem;
    padding: var(--wp--preset--spacing--50);
    transition: box-shadow 0.25s ease, transform 0.25s ease;
  }

  .sya-cat-card:hover,
  .sya-cat-card:focus-within {
    box-shadow: 0 16px 40px color-mix(in oklch, var(--wp--preset--color--contrast) 12%, transparent);
    transform: translateY(-2px);
  }

  .sya-cat-icon {
    display: block;
    color: var(--wp--preset--color--primary);
    margin-block-end: var(--wp--preset--spacing--40);
  }

  .sya-cat-card .wp-block-heading a {
    color: inherit;
    text-decoration: none;
  }

  /* Stretched link — whole card is clickable. */
  .sya-cat-card .wp-block-heading a::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
  }

  .sya-cat-card:hover .wp-block-heading a,
  .sya-cat-card .wp-block-heading a:focus-visible {
    text-decoration: underline;
  }

  .sya-cat-more {
    color: var(--wp--preset--color--primary);
    margin-block-end: 0;
  }

  @media (prefers-reduced-motion: reduce) {
    .sya-cat-card {
      transition: none;
    }

    .sya-cat-card:hover,
    .sya-cat-card:focus-within {
      transform: none;
    }
  }

  /* Blog index cards (home.html — the /blogi/ Posts page). The post-template
     uses WP's native grid layout (minimumColumnWidth), so only the card
     styling lives here: same white rounded surface as the event cards, with a
     featured image on top and a padded text body. Card is a flex column so the
     featured image sits flush above the body. */
  .sya-blog .wp-block-post {
    background: #fff;
    border-radius: 2rem;
    overflow: hidden;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    height: 100%;
  }

  .sya-blog .wp-block-post-featured-image {
    margin: 0;
  }

  .sya-blog-card__body {
    padding: var(--wp--preset--spacing--50);
  }

  .sya-blog-card__body .wp-block-post-date {
    font-size: 0.85rem;
    font-style: italic;
    color: var(--wp--preset--color--primary);
  }

  .sya-blog-card__body .wp-block-post-title {
    font-size: 1.5rem;
    line-height: 1.15;
    margin-block: 0;
  }

  .sya-blog-card__body .wp-block-post-title a {
    color: var(--wp--preset--color--contrast);
    text-decoration: none;

    &:hover,
    &:focus-visible {
      text-decoration: underline;
    }
  }

  .sya-blog-more {
    color: var(--wp--preset--color--primary);
    font-weight: 700;
    text-decoration: none;

    &:hover,
    &:focus-visible {
      text-decoration: underline;
    }
  }

  /* Reduced-motion — disable transforms and transitions */
  @media (prefers-reduced-motion: reduce) {
    .sya-back-link__arrow,
    .sya-anchor-cta__arrow,
    .sya-trainer-card,
    .sya-upcoming-card,
    .sya-anchor-cta,
    .sya-pdf-button {
      transition: none;
    }
  }
}

/* ==========================================================================
   Styles outside @layer so they're globally accessible
   ========================================================================== */


/* Sizing the inner img is unlayered because WP block layout CSS
   ships unlayered (`.wp-block-post-featured-image img { height: auto }`)
   which overrides any `block-size: 100%` defined inside @layer. */
main .sya-henkilo-single .wp-block-post-featured-image img,
main .sya-henkilo-single__photo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: top;
  border-radius: 0;
}

/* Blog card thumbnails — a fixed-height banner cropped across the top of each
   card. Unlayered for the same reason as above (WP core's unlayered
   `.wp-block-post-featured-image img { height: auto }` would beat a layered
   rule). A fixed block-size + overflow:hidden avoids the aspect-ratio/
   percentage-height circular sizing loop that let portrait covers render
   full-height; the isLink <a> also fills so object-fit can crop. */
.sya-blog .wp-block-post-featured-image {
  block-size: clamp(180px, 22vw, 240px);
  overflow: hidden;
}

.sya-blog .wp-block-post-featured-image a,
.sya-blog .wp-block-post-featured-image img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

@keyframes clipPathCircleOpen {
  0% {
    clip-path: circle(0% at top right);
  }
  100% {
    clip-path: circle(250% at top right);
  }
}

@keyframes clipPathCircleClose {
  0% {
    clip-path: circle(250% at top right);
  }
  100% {
    clip-path: circle(0% at top right);
  }
}

/* Book cover — prominent featured image in the main column
   Unlayered: WP core .wp-block-post-featured-image :where(img) is unlayered
   and would otherwise beat any @layer rule. By pulling these to the top level
   and relying on declaration order, our rules win. */
/* Category-card grid (#46 Koulutustarjontamme). Unlayered so it beats WP's
   unlayered layout CSS for the wrapping group (same escape-hatch rationale as
   the featured-image rule below). Scoped to .sya-cat-grid — not a global reset.
   One fluid gap on both axes; collapses to a single column on small screens. */
.sya-cat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

.sya-cat-grid > * {
  margin-block-start: 0;
}

@media (max-width: 600px) {
  .sya-cat-grid {
    grid-template-columns: 1fr;
  }
}

/* Koulutus archive (archive-koulutus.html) card grid. Same escape-hatch
   rationale as .sya-cat-grid — unlayered so WP's unlayered layout CSS for the
   wrapping group doesn't beat it. Holds the shared .sya-event-card cards
   (from [koulutus_kalenteri_cards]) as a wrapping grid instead of the
   carousel's fixed-width scroll row. auto-fit collapses empty tracks so a
   handful of courses still fill the row; cards have height:100% for equal
   heights. min(100%, 300px) prevents overflow on narrow screens. */
.sya-koulutus-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: stretch;
}

.sya-koulutus-grid > * {
  margin-block-start: 0;
}

.sya-kirja-cover {
  margin-block-end: var(--wp--preset--spacing--50);
}

.sya-kirja-cover img {
  inline-size: auto;
  max-inline-size: 100%;
  block-size: auto;
  display: block;
  border-radius: var(--wp--preset--border-radius--small, 4px);
  box-shadow:
    0 2px 6px color-mix(in oklch, var(--wp--preset--color--contrast) 14%, transparent),
    0 16px 40px color-mix(in oklch, var(--wp--preset--color--contrast) 24%, transparent);
}
