/*
Theme Name: WorkXcape
Theme URI:
Author: Räikee Oy
Author URI:
Description: WorkXcape block theme — workplace wellbeing coach site that accompanies the Phaser HTML5 game.
Version: 0.1.10
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: workxcape
Tags: block-patterns, block-styles, full-site-editing, wide-blocks
*/

/* ==========================================================================
   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 (auto-wrapped via functions.php for cascade control)
   3. base      — Global element defaults (in this file)
   4. tokens    — Design system tokens via CSS custom properties (in this file)
   5. header    — Header/navigation styles (see assets/css/header.css)
   6. components — Reusable component styles (see styles/blocks/core/*.css)
   7. utilities — Helper & utility classes (in this file)
   8. overrides — High-specificity client overrides (add your custom CSS here)

   Note: reset, base, tokens, and utilities are defined in this file.
   wpglobal layer wraps WP's global-styles-inline-css to make it overridable by other layers.
   header styles live in assets/css/header.css (enqueued via functions.php).
   Block-specific CSS lives in styles/blocks/core/ (auto-enqueued via functions.php).
*/

/* Layer order is also declared early in functions.php (wp_head priority 1) to ensure
   wpglobal is positioned correctly before WordPress outputs global-styles-inline-css.
   If you change this order, update functions.php to match.

   wpglobal is the @layer wrapper for WP's global-styles-inline-css (see functions.php
   wp_print_styles hook). Because it's named and positioned early, any layer declared
   after it (base → overrides) can override WP layout rules — including .is-layout-flow
   blockGap margins — without !important. */
@layer reset, wpglobal, base, tokens, atmosphere, 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;
    hyphens: auto;
  }

  :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;
  }

  /* Flow/constrained layout spacing — override wpglobal blockGap defaults.
     WP applies margin-block-start to ALL layout children (both .is-layout-flow and
     .is-layout-constrained). We restore spacing only for content-level elements so
     container blocks (group, cover, columns, template-part) stay at 0.

     Covers both block editor classes (.wp-block-*) and plain HTML elements —
     post content outputs bare <p>/<blockquote> etc. with no block class.
     Excludes :first-child to avoid unwanted top margin at the start of a container. */
  :is(.is-layout-flow, .is-layout-constrained)
    > :where(
      p,
      h1,
      h2,
      h3,
      h4,
      h5,
      h6,
      blockquote,
      ul,
      ol,
      figure,
      hr,
      .wp-block-paragraph,
      .wp-block-heading,
      .wp-block-list,
      .wp-block-quote,
      .wp-block-pullquote,
      .wp-block-image,
      .wp-block-gallery,
      .wp-block-buttons,
      .wp-block-table,
      .wp-block-separator
    ):not(:first-child) {
    margin-block-start: var(--wp--preset--spacing--40);
  }

  /* 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);
    }
  }
}

/* ==========================================================================
   Atmosphere
   Folkloric cartography visual layer. Leaf-as-map parallax, sparks, grain,
   shape-outside flows. Every motion gated behind prefers-reduced-motion.
   ========================================================================== */

@layer atmosphere {

  /* Decorative tokens — extend palette for atmospheric accents.
     Not in theme.json palette to keep the editor UI lean. */
  :root {
    --wx-ember:  oklch(52% 0.17 45);             /* deeper than primary, glows */
    --wx-moss:   oklch(20% 0.035 125);           /* hint of forest in darkest bg */
    --wx-ash:    oklch(28% 0.01 65);             /* warm mid-tone for dividers */
    --wx-ink:    oklch(8% 0.005 60);             /* deeper than base for wells  */

    /* Shared parallax scaffolding. Each parallax element sets its own
       animation using these timings; the timeline is the scroll root. */
    --wx-parallax-duration: 1;
  }

  /* Grain overlay via SVG filter — stays crisp at any resolution, 0KB.
     Applied to .has-wx-grain surfaces. Low opacity so it whispers. */
  .has-wx-grain {
    position: relative;
    isolation: isolate;
  }
  .has-wx-grain::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0.08;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.9'/></svg>");
    z-index: 1;
  }

  /* ---------- Leaf-as-map atmosphere wrapper ---------- */

  .wx-atmosphere {
    position: relative;
    isolation: isolate;
    overflow: clip;

    /* Moody depth — radial glows composited over the block's base bg.
       Reads as "firelight somewhere off-frame" + soft top-left wash. */
    background-image:
      radial-gradient(
        ellipse 120% 70% at 82% 115%,
        color-mix(in oklch, var(--wx-ember) 55%, transparent) 0%,
        color-mix(in oklch, var(--wx-ember) 20%, transparent) 28%,
        transparent 62%
      ),
      radial-gradient(
        ellipse 80% 55% at 8% -5%,
        color-mix(in oklch, var(--wp--preset--color--primary) 28%, transparent) 0%,
        transparent 60%
      ),
      radial-gradient(
        ellipse 160% 120% at 50% 50%,
        transparent 35%,
        color-mix(in oklch, var(--wx-ink) 80%, transparent) 100%
      );
  }

  /* Vignette wash over the leaf — pulls veins back from the centre so the
     type sits in a "clearing". Lighter now that veins are themselves more
     transparent — just enough to anchor the headline. */
  .wx-atmosphere::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    background:
      radial-gradient(
        ellipse 50% 38% at 50% 48%,
        color-mix(in oklch, var(--wp--preset--color--base) 70%, transparent) 0%,
        color-mix(in oklch, var(--wp--preset--color--base) 35%, transparent) 45%,
        transparent 75%
      );
  }

  /* Content sits above everything atmospheric. Excludes elements that manage
     their own positioning (absolute overlays like .wx-seal). */
  .wx-atmosphere > :not(.wx-leaf):not(.wx-sparks):not(.wx-seal) {
    position: relative;
    z-index: 2;
  }

  /* The leaf image as a cartographic backdrop. Pre-zoomed asset (veins only,
     no leaf silhouette). Fills the atmosphere block via object-fit. Copper
     tint via filter composes with screen blend and the warm gradient
     backdrop — veins read as forged metal filaments, not a plant. */
  /* Copper glow comes from overlay blend composing the white vein PNG with
     the warm ember gradient underneath — no filter hue-rotate needed, that
     was a no-op on a monochrome source. */
  .wx-leaf {
    position: absolute;
    inset: 0;
    pointer-events: none;
    user-select: none;
    max-width: 100%;
    height: auto;
    opacity: 0.2;
    mix-blend-mode: overlay;
    z-index: 0;
  }

  /* ---------- Sparks — warm embers drifting upward ---------- */

  .wx-sparks {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    overflow: clip;
  }

  .wx-spark {
    position: absolute;
    inline-size: 2px;
    block-size: 2px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
    box-shadow:
      0 0 4px  var(--wp--preset--color--accent),
      0 0 10px color-mix(in oklch, var(--wp--preset--color--accent) 60%, transparent);
    opacity: 0;
    inset-block-end: -10px;
  }

  @media (prefers-reduced-motion: no-preference) {
    .wx-spark {
      animation: wx-spark-drift var(--wx-d, 12s) var(--wx-delay, 0s) infinite linear;
    }
    @keyframes wx-spark-drift {
      0%   { transform: translate3d(0, 0, 0) scale(1);   opacity: 0; }
      10%  { opacity: 0.9; }
      50%  { transform: translate3d(var(--wx-x, 20px), -50vh, 0) scale(0.8); opacity: 0.7; }
      90%  { opacity: 0.3; }
      100% { transform: translate3d(var(--wx-x, 20px), -110vh, 0) scale(0.3); opacity: 0; }
    }
  }

  /* ---------- Organic section divider ---------- */

  .wx-divider {
    position: relative;
    display: block;
    inline-size: 100%;
    block-size: clamp(60px, 8vw, 120px);
    pointer-events: none;
  }
  .wx-divider svg {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    display: block;
  }
  .wx-divider path {
    fill: var(--wp--preset--color--base);
  }

  /* ---------- Type: WORKXCAPE forged / copper gradient fill ---------- */

  .wx-forged {
    background: linear-gradient(
      180deg,
      var(--wp--preset--color--contrast) 0%,
      color-mix(in oklch, var(--wp--preset--color--contrast) 60%, var(--wp--preset--color--primary)) 45%,
      var(--wp--preset--color--primary) 75%,
      var(--wx-ember) 100%
    );
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    text-shadow:
      0 0 30px color-mix(in oklch, var(--wx-ember) 40%, transparent),
      0 0 60px color-mix(in oklch, var(--wp--preset--color--primary) 20%, transparent);
    /* Fallback solid colour for browsers without background-clip: text */
    @supports not (background-clip: text) {
      color: var(--wp--preset--color--contrast);
      background: none;
    }
  }

  /* ---------- Shape-outside flow helpers ---------- */

  .wx-shape-left,
  .wx-shape-right {
    max-width: 100%;
    inline-size: clamp(300px, 42vw, 560px);
    height: auto;
    shape-outside: url("assets/images/leaf-700.webp");
    shape-image-threshold: 0.5;
    shape-margin: 1.5rem;
    margin-block-start: 0.25rem;
    opacity: 0.35;
    mix-blend-mode: overlay;
    /* Each floated leaf gets its own territory in a long flow — clear any
       previous float so leaves don't stack on the same side. */
    clear: both;
  }
  .wx-shape-left {
    float: inline-start;
    margin-inline-end: 1.5rem;
  }
  .wx-shape-right {
    float: inline-end;
    margin-inline-start: 1.5rem;
    transform: scaleX(-1);
  }

  /* In a continuous-prose section, each topic starts with an h2 that should
     break below any previous float so topics read cleanly.
     Buttons also clear so they sit at full content width (centered via
     WP's constrained-layout max-width) instead of being squeezed next to a
     shape-outside leaf — that was causing the "inconsistent width" feel. */
  .wx-prose-flow h2,
  .wx-prose-flow .wx-eyebrow,
  .wx-prose-flow .wp-block-buttons {
    clear: both;
  }

  /* ---------- Topic with organic shape-outside leaf flow ----------
     Each topic is a BFC (display:flow-root) so the floated leaf is contained
     inside its own topic and can't leak into adjacent ones. The leaf is a
     float with shape-outside so text flows around its irregular silhouette.
     Leaf sized compactly (~240x340 max) so topics stay tight. Buttons clear
     so they sit at full width below, not awkwardly wrapping around the leaf. */

  .wx-topic {
    display: flow-root;
  }
  .wx-topic__shape {
    inline-size: clamp(200px, 24vw, 260px);
    block-size: auto;
    max-block-size: 360px;
    object-fit: contain;
    /* Default: theme leaf silhouette. Override per instance via inline
       style="--wx-shape-url: url(<media>)" for any image with transparency. */
    shape-outside: var(--wx-shape-url, url("assets/images/leaf-700.webp"));
    shape-image-threshold: 0.5;
    shape-margin: 1.25rem;
    margin-block-start: 0.5rem;
    opacity: 0.5;
    filter: grayscale(25%) contrast(1.05);
  }
  .wx-topic__shape--right {
    float: inline-end;
    margin-inline-start: 1.5rem;
    transform: scaleX(-1);
  }
  .wx-topic__shape--left {
    float: inline-start;
    margin-inline-end: 1.5rem;
  }
  /* Small faded tag list (used in Palvelut section) */
  .wx-tags {
    font-size: 0.78rem;
    opacity: 0.55;
    line-height: 1.9;
  }
  @media (max-width: 600px) {
    .wx-topic__shape--right,
    .wx-topic__shape--left {
      float: none;
      display: block;
      inline-size: 60%;
      margin-inline: auto;
      max-block-size: 220px;
      opacity: 0.3;
    }
  }

  /* ---------- Hero/content clip (polygon) ----------
     25-vertex polygon approximating Bezier Q-curves sampled at midpoints.
     Bottom 7% jagged (y 93–100%); rest full visibility.
     Content pulled up -7vh so its flat top hides behind hero, shows through
     where hero is clipped. overflow:visible overrides the base .wx-atmosphere
     rule so clip-path can render cleanly. */

  .wx-atmosphere--hero {
    overflow: visible;
    position: relative;
    z-index: 2;
    clip-path: polygon(
      0 0,
      100% 0,
      100% 95.8%,
      97.92% 96.5%,
      95.83% 97.67%,
      91.67% 97.55%,
      87.5% 95.33%,
      83.33% 96.97%,
      79.17% 100%,
      75% 97.78%,
      70.83% 93%,
      66.25% 94.75%,
      61.67% 98.13%,
      57.5% 97.32%,
      53.33% 93.93%,
      49.17% 96.62%,
      45% 100%,
      41.67% 98.48%,
      38.33% 94.87%,
      34.17% 96.38%,
      30% 99.07%,
      25.83% 96.85%,
      21.67% 93%,
      16.67% 94.52%,
      11.67% 97.2%,
      5.83% 97.2%,
      0 95.33%
    );
  }
  .wx-atmosphere--quiet {
    margin-block-start: -7vh;
    /* Offset the -7vh overlap so actual content starts below hero's full box —
       otherwise text sits in the overlap zone and gets covered at jag peaks.
       !important beats the inline padding-top the pattern ships with. */
    padding-block-start: calc(var(--wp--preset--spacing--70) + 7vh) !important;
  }

  /* ---------- Hero frame — asymmetric poster composition ---------- */

  .wx-hero-frame {
    position: relative;
    z-index: 2;
    max-inline-size: min(94vw, 1600px);
    margin-inline: auto;
    min-block-size: 75vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(1.25rem, 3.5vw, 2.75rem);
    padding-block: clamp(2rem, 6vw, 4rem);
  }

  .wx-hero-eyebrow {
    align-self: flex-start;
    /* Align eyebrow with the 1200px content column below, even though the hero
       frame itself is wider (1600px). On narrower viewports this collapses to 0. */
    margin-inline-start: max(0px, calc((100% - 1200px) / 2));
    display: flex;
    align-items: center;
    gap: 0.85em;
    margin-block-end: clamp(0.5rem, 3vh, 1.5rem);
    font-family: var(--wp--preset--font-family--condensed);
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: var(--wp--custom--letter-spacing--poster, 0.4em);
    color: var(--wp--preset--color--primary);
  }
  .wx-hero-eyebrow::before {
    content: "";
    inline-size: 2.5em;
    block-size: 1px;
    background: currentColor;
    opacity: 0.7;
  }

  /* Poster H1: single line, sized to fit viewport without clipping.
     Measured char width ~6.67em → 13vw keeps WORKXCAPE ~87% of viewport. */
  .wx-poster {
    display: block;
    inline-size: 100%;
    margin-block: 0;
    text-align: center;
    font-family: var(--wp--preset--font-family--display);
    font-weight: 900;
    font-size: clamp(2.75rem, 13vw, 12rem);
    line-height: 0.85;
    letter-spacing: -0.055em;
    text-transform: uppercase;
    white-space: nowrap;
  }

  /* Mantra — four words, hammer-strike reveal on load. */
  .wx-mantra {
    margin-block: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5em 1.75em;
    font-family: var(--wp--preset--font-family--condensed);
    font-size: clamp(1rem, 1.9vw, 1.5rem);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.26em;
    color: var(--wp--preset--color--secondary);
  }
  .wx-mantra span {
    position: relative;
    display: inline-block;
  }
  .wx-mantra span + span::before {
    content: "·";
    position: absolute;
    inset-inline-start: -1em;
    color: var(--wp--preset--color--primary);
    opacity: 0.8;
  }

  @media (prefers-reduced-motion: no-preference) {
    .wx-mantra span {
      opacity: 0;
      translate: 0 0.5em;
      filter: blur(6px);
      animation: wx-forge-in 900ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
      animation-delay: calc(var(--i, 0) * 180ms + 500ms);
    }
    @keyframes wx-forge-in {
      0%   { opacity: 0; translate: 0 0.6em; filter: blur(6px); }
      60%  { opacity: 1;                      filter: blur(0.5px); }
      100% { opacity: 1; translate: 0 0;      filter: none; }
    }
  }

  /* ---------- CTA row ---------- */

  .wx-cta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: clamp(1rem, 2.5vw, 2rem);
    margin-block-start: clamp(0.5rem, 2vw, 1.25rem);
  }

  /* Forged medallion: hand-cut rock silhouette via clip-path polygon.
     - 10 uneven vertices = chiseled, not stamped.
     - Outer glow uses filter:drop-shadow() (respects clip-path).
     - Inset highlights/shadows live inside the clipped region.
     - Applies to: hand-written .wx-forge-btn anchors (hero) AND core WP buttons
       when they are the first (or only) button in a .wp-block-buttons group.
       Siblings after the first auto-fall-through to the text-link style below. */
  .wx-forge-btn,
  .wp-block-buttons > .wp-block-button:first-child > .wp-block-button__link {
    --wx-forge-shape: polygon(
      1% 28%, 16% 4%, 52% 0%, 78% 4%, 100% 14%,
      96% 52%, 94% 82%, 62% 100%, 22% 96%, 0% 72%
    );
    --wx-forge-shape-hover: polygon(
      4% 22%, 20% 6%, 48% 2%, 82% 6%, 98% 16%,
      100% 50%, 96% 86%, 58% 98%, 18% 92%, 2% 66%
    );
    display: inline-flex;
    align-items: center;
    gap: 0.7em;
    padding: 1.15em 2.4em;
    background: linear-gradient(
      180deg,
      color-mix(in oklch, var(--wp--preset--color--accent) 92%, white) 0%,
      var(--wp--preset--color--accent) 45%,
      color-mix(in oklch, var(--wp--preset--color--accent) 78%, var(--wx-ember)) 100%
    );
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
    font-family: var(--wp--preset--font-family--condensed);
    font-weight: 700;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    clip-path: var(--wx-forge-shape);
    box-shadow:
      inset 0 1px 0 color-mix(in oklch, var(--wp--preset--color--contrast) 35%, transparent),
      inset 0 -2px 6px color-mix(in oklch, black 35%, transparent);
    filter:
      drop-shadow(0 10px 18px color-mix(in oklch, var(--wx-ember) 28%, transparent))
      drop-shadow(0 2px 0 color-mix(in oklch, var(--wp--preset--color--primary) 85%, transparent));
    cursor: pointer;
    transition:
      translate 240ms ease,
      filter 240ms ease,
      clip-path 500ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .wx-forge-btn:hover,
  .wx-forge-btn:focus-visible,
  .wp-block-buttons > .wp-block-button:first-child > .wp-block-button__link:hover,
  .wp-block-buttons > .wp-block-button:first-child > .wp-block-button__link:focus-visible {
    translate: 0 -1px;
    clip-path: var(--wx-forge-shape-hover);
    box-shadow:
      inset 0 1px 0 color-mix(in oklch, var(--wp--preset--color--contrast) 48%, transparent),
      inset 0 -2px 6px color-mix(in oklch, black 45%, transparent);
    filter:
      drop-shadow(0 14px 24px color-mix(in oklch, var(--wp--preset--color--accent) 55%, transparent))
      drop-shadow(0 0 28px color-mix(in oklch, var(--wx-ember) 45%, transparent))
      drop-shadow(0 2px 0 color-mix(in oklch, var(--wp--preset--color--primary) 90%, transparent));
  }
  .wx-forge-btn:focus-visible,
  .wp-block-buttons > .wp-block-button:first-child > .wp-block-button__link:focus-visible {
    filter:
      drop-shadow(0 0 0 2px var(--wp--preset--color--primary))
      drop-shadow(0 14px 24px color-mix(in oklch, var(--wp--preset--color--accent) 55%, transparent))
      drop-shadow(0 0 28px color-mix(in oklch, var(--wx-ember) 45%, transparent));
  }
  .wx-forge-btn__arrow {
    transition: translate 200ms ease;
    flex-shrink: 0;
  }
  .wx-forge-btn:hover .wx-forge-btn__arrow,
  .wx-forge-btn:focus-visible .wx-forge-btn__arrow {
    translate: 3px 0;
  }

  /* Secondary: plain text link with hand-drawn arrow. Border appears on hover. */
  .wx-text-link {
    display: inline-flex;
    align-items: center;
    gap: 0.6em;
    padding-block-end: 0.4em;
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
    font-family: var(--wp--preset--font-family--condensed);
    font-weight: 500;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    border-block-end: 1px solid transparent;
    transition: color 200ms ease, border-color 200ms ease;
  }
  .wx-text-link:hover,
  .wx-text-link:focus-visible {
    color: var(--wp--preset--color--primary);
    border-block-end-color: color-mix(in oklch, var(--wp--preset--color--primary) 50%, transparent);
  }
  .wx-text-link:focus-visible {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 4px;
  }
  .wx-text-link__arrow {
    transition: translate 200ms ease;
    flex-shrink: 0;
  }
  .wx-text-link:hover .wx-text-link__arrow,
  .wx-text-link:focus-visible .wx-text-link__arrow {
    translate: 4px 0;
  }

  /* Second-and-beyond button in a .wp-block-buttons pair → text-link treatment.
     Resets core-button paint (bg/padding/radius/shadow/clip) then applies the
     .wx-text-link visual. Hero's hand-written pair stays untouched (not core markup). */
  .wp-block-buttons > .wp-block-button:nth-child(n+2) > .wp-block-button__link {
    background: none;
    padding: 0 0 0.4em;
    border: none;
    border-radius: 0;
    clip-path: none;
    box-shadow: none;
    filter: none;
    color: var(--wp--preset--color--contrast);
    text-decoration: none;
    font-family: var(--wp--preset--font-family--condensed);
    font-weight: 500;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    border-block-end: 1px solid transparent;
    transition: color 200ms ease, border-color 200ms ease;
  }
  .wp-block-buttons > .wp-block-button:nth-child(n+2) > .wp-block-button__link:hover,
  .wp-block-buttons > .wp-block-button:nth-child(n+2) > .wp-block-button__link:focus-visible {
    color: var(--wp--preset--color--primary);
    border-block-end-color: color-mix(in oklch, var(--wp--preset--color--primary) 50%, transparent);
  }

  /* ---------- 76100 seal — hand-stamped postmark, bottom-right ---------- */

  .wx-seal {
    position: absolute;
    z-index: 3;
    inset-inline-end: clamp(1rem, 4vw, 4rem);
    inset-block-end: clamp(1.5rem, 4vw, 5rem);
    inline-size: clamp(96px, 12vw, 150px);
    aspect-ratio: 1;
    color: var(--wp--preset--color--primary);
    rotate: -5deg;
    opacity: 0.92;
    pointer-events: none;
    filter: drop-shadow(0 0 30px color-mix(in oklch, var(--wx-ember) 22%, transparent));
  }
  .wx-seal__frame {
    position: relative;
    inline-size: 100%;
    block-size: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.25em;
    border: 1px solid currentColor;
    border-radius: 50%;
    background: radial-gradient(
      circle at 30% 30%,
      color-mix(in oklch, var(--wx-ember) 10%, transparent) 0%,
      color-mix(in oklch, var(--wx-ember)  2%, transparent) 100%
    );
    font-family: var(--wp--preset--font-family--condensed);
    font-size: clamp(0.625rem, 0.9vw, 0.78rem);
  }
  .wx-seal__frame::before {
    content: "";
    position: absolute;
    inset: clamp(5px, 0.8vw, 8px);
    border: 1px dashed currentColor;
    border-radius: 50%;
    opacity: 0.5;
  }
  .wx-seal__frame::after {
    content: "✦";
    position: absolute;
    inset-block-start: 14%;
    font-size: 0.8em;
    opacity: 0.75;
    line-height: 1;
  }
  .wx-seal__num {
    font-family: var(--wp--preset--font-family--display);
    font-weight: 900;
    font-size: 2em;
    letter-spacing: 0.04em;
    line-height: 1;
    color: var(--wp--preset--color--primary);
  }
  .wx-seal__rule {
    inline-size: 34%;
    block-size: 1px;
    background: currentColor;
    opacity: 0.55;
    margin-block: 0.15em;
  }
  .wx-seal__label {
    font-weight: 600;
    font-size: 0.9em;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    line-height: 1;
  }
  .wx-seal__kicker {
    font-size: 0.68em;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    opacity: 0.6;
    margin-block-start: 0.1em;
  }

  /* On narrow screens, drop shape-outside floats — text wrap around a float
     gets awkward below ~600px. Image becomes a top decoration. Also rebalance
     hero for phones — poster text shrinks to fit, CTAs stack. */
  @media (max-width: 600px) {
    .wx-shape-left,
    .wx-shape-right {
      float: none;
      display: block;
      margin-inline: auto;
      inline-size: 60%;
      opacity: 0.22;
    }
    .wx-poster {
      font-size: min(12vw, 3.25rem);
      letter-spacing: -0.04em;
      line-height: 0.88;
    }
    .wx-hero-eyebrow {
      font-size: 0.7rem;
      letter-spacing: 0.3em;
      gap: 0.55em;
    }
    .wx-hero-eyebrow::before {
      inline-size: 1.5em;
    }
    .wx-mantra {
      gap: 0.3em 1.1em;
      font-size: 0.8rem;
      letter-spacing: 0.2em;
    }
    .wx-cta-row {
      flex-direction: column;
      align-items: center;
      inline-size: 100%;
    }
    /* Game isn't mobile-optimised — hide the game CTA on phones. */
    .wx-forge-btn {
      display: none;
    }
    .wx-text-link {
      justify-content: center;
    }
    .wx-seal {
      inset-inline-end: 0.75rem;
      inset-block-end: 1rem;
      inline-size: 84px;
      rotate: -4deg;
    }
  }
}

/* ==========================================================================
   Header
   ========================================================================== */

@layer header {
  .wp-block-template-part:has(.site-header) {
    position: fixed;
    inset-block-start: 0;
    inline-size: 100%;
    z-index: var(--wp--custom--z-index--sticky, 200);
  }

  .site-header {
    background: transparent;
    transition: background var(--wp--custom--timing--normal);
  }

  .site-header.is-stuck {
    background: var(--wp--preset--color--base);
    box-shadow: var(--wp--preset--shadow--md);
  }
}

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

@layer utilities {
  /* 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);
  }

  .hienolista {
    li {
      margin-block-start: 10px;

      &::before {
        content: "✓";
        color: var(--wp--preset--color--primary);
        font-weight: 700;
        margin-inline-end: 0.5em;
      }
    }
  }
}

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

main {
  &,
  & > * {
    margin-block-start: 0;
  }
}

@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);
  }
}
