/*
 * IRZ Visual & Interaction Redesign
 * ----------------------------------------------------------------------------
 * Reusable, opt-in animation + interaction layer for the Beiged/IRZ theme.
 *
 * How this file is organised:
 *   0. Design tokens
 *   1. No-FOUC gate (see irz-interactions.js)
 *   2. Typography
 *   3. Section labels / editorial details
 *   4. Navigation
 *   5. Buttons
 *   6. Cards (generic + "Naši ciljevi i planovi" goal cards)
 *   7. Images (hover zoom + mask reveal)
 *   8. Scroll reveal system (.irz-reveal*, .irz-stagger*)
 *   9. Hero: decorative geometry + entrance
 *  10. Recent posts / editorial cards (post carousel)
 *  11. Subtle background texture
 *  12. Interactive dot-grid background (.irz-dot-grid, .irz-dot-grid-canvas)
 *  13. Reduced motion + mobile
 *  14. Projects (archive-project.html + single-project.html)
 *
 * Two kinds of selectors are used throughout:
 *   a) Generic, reusable "irz-*" classes — add these to any block via
 *      Block -> Advanced -> Additional CSS class(es) in the Gutenberg / Site
 *      Editor. This is the primary, future-proof mechanism (see spec §34).
 *   b) A handful of precise selectors scoped to stable structural markers
 *      already present on the live homepage (e.g. block ids such as
 *      .uagb-block-11896279, or unique class/background combinations) so
 *      the redesign takes effect immediately without editing DB content.
 *      These are commented with which live section they target.
 */

/* ==========================================================================
   0. Design tokens
   ========================================================================== */
:root {
  /* Brand — sampled from the live logo (institutecd.eu uploads), matches
     the palette entry registered in theme.json as "irz-red". */
  --irz-red: var(--wp--preset--color--irz-red, #c92d32);
  --irz-red-soft: var(--wp--preset--color--irz-red-soft, #f4e6e4);
  --irz-black: var(--wp--preset--color--primary, #000000);
  --irz-bg: var(--wp--preset--color--base, #efebe5);
  --irz-bg-alt: var(--wp--preset--color--mono-4, #f7f2ea);
  --irz-text: var(--wp--preset--color--mono-1, #111111);
  --irz-text-muted: var(--wp--preset--color--mono-2, #8b8883);

  --irz-space-xs: 8px;
  --irz-space-sm: 16px;
  --irz-space-md: 24px;
  --irz-space-lg: 40px;
  --irz-space-xl: 64px;
  --irz-space-2xl: 96px;
  --irz-space-3xl: 140px;

  --irz-radius-sm: 6px;
  --irz-radius-md: 10px;
  --irz-radius-lg: 16px;

  --irz-shadow-sm: 0 8px 25px rgba(0, 0, 0, 0.05);
  --irz-shadow-md: 0 18px 45px rgba(0, 0, 0, 0.08);

  --irz-transition-fast: 200ms ease;
  --irz-transition: 350ms ease;
  --irz-transition-slow: 700ms cubic-bezier(0.2, 0.8, 0.2, 1);

  --irz-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ==========================================================================
   1. No-FOUC gate
   Content only ever hides behind opacity:0 when JS has confirmed it can
   also reveal it again (irz-js on <html>) AND the visitor allows motion.
   With JS disabled, or reduced motion requested, nothing is ever hidden.
   The ":not(.is-visible)" guard is load-bearing: without it, this rule's
   higher specificity (3 classes) would permanently beat the "reveal it"
   rule in §8 (2 classes) once .is-visible is added, leaving content
   stuck invisible forever instead of just until it scrolls into view.
   ========================================================================== */
.irz-js:not(.irz-reduced-motion) .irz-reveal:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-reveal-up:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-reveal-left:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-reveal-right:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-reveal-scale:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-stagger-item:not(.is-visible),
.irz-js:not(.irz-reduced-motion) .irz-reveal-image:not(.is-visible) {
  opacity: 0;
  will-change: opacity, transform;
}

/* ==========================================================================
   2. Typography
   ========================================================================== */
.irz-hero-heading {
  font-size: clamp(42px, 6vw, 82px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.01em;
}

.irz-section-heading,
h2.uagb-heading-text {
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.005em;
}

body,
p {
  line-height: 1.6;
}

.irz-meta,
.irz-section-label {
  font-size: 13px;
  letter-spacing: 0.08em;
}

/* ==========================================================================
   3. Section labels / editorial details
   Small red kicker labels, e.g. "01 / NAŠ PRISTUP" above a heading.
   Add class "irz-section-label" to a paragraph placed just above a heading.
   ========================================================================== */
.irz-section-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 var(--irz-space-xs);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--irz-red);
}

.irz-section-label::before {
  content: "";
  width: 16px;
  height: 1px;
  background: currentColor;
}

/* A small animated red rule under a heading, e.g. under "Kako radimo?".
   Add class "irz-section-accent" to a heading to get it. */
.irz-section-accent {
  position: relative;
  padding-bottom: var(--irz-space-sm);
}

.irz-section-accent::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 48px;
  height: 2px;
  background: var(--irz-red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--irz-transition-slow);
}

.irz-section-accent.is-visible::after,
.irz-reduced-motion .irz-section-accent::after {
  transform: scaleX(1);
}

/* ==========================================================================
   4. Navigation
   Fixed, glassy header that hides on scroll down and reveals on scroll up
   (see initHeaderAutoHide() in irz-interactions.js §7) — same pattern as
   the floating translucent nav at mobilitylab.ch/de.
   ========================================================================== */
.superbthemes-navigation-three {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  transition: padding var(--irz-transition), transform var(--irz-transition-slow);
}

/* Fixed positioning takes the header out of flow, so without this every
   page's content would start right under the (transparent) header and
   the first section's top would render partly hidden behind it at rest.
   The 92px fallback is a plain-CSS/no-JS safety net (measured from the
   header's own rendered height); with JS enabled, initHeaderAutoHide()
   overwrites it with the header's actual current height instead.
   The flex rules below are a sticky footer: on a page short enough that
   its content doesn't fill the viewport (a fresh About/Contact page, or
   a Projects archive with only a card or two so far), the footer would
   otherwise sit right under the content instead of the bottom of the
   screen. Targets ".wp-site-blocks" (the wrapper WordPress itself puts
   around header/main/footer), not body directly — body's own children
   are that wrapper plus a handful of unrelated script tags and the
   skip-link, not the actual page structure. The header, despite being a
   DOM child of that wrapper, doesn't count as a flex item here —
   position:fixed elements are excluded from flex layout entirely, same
   as they're excluded from normal flow — so this only ever touches the
   two children that actually remain: main and footer. */
body {
  padding-top: var(--irz-header-height, 92px);
}

.wp-site-blocks {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.wp-site-blocks > main {
  flex: 1 0 auto;
}

.irz-header-hidden.superbthemes-navigation-three {
  /* -120%, not -100%: at exactly -100% the pill's own drop-shadow would
     still be peeking in over the top edge mid-transition. */
  transform: translateY(-120%);
}

.superbthemes-navigation-three > .wp-block-group {
  /* Glassy always, not just once scrolled — scoped to this specific pill
     (a direct child of the nav) rather than the bare
     ".has-featured-background-color" class it also carries, which the
     unrelated "Poziv na suradnju" CTA section elsewhere on the page also
     uses and which should keep its solid background. rgba below is the
     "featured" preset's own color (#f7f2ea, same as --irz-bg-alt) with
     alpha added — can't reuse the token directly through a plain rgba().
     Alpha is high (0.88) and the blur heavy (24px) deliberately: a lower
     alpha read as too see-through — more like plain tinted glass than
     the frosted, stained-glass look intended, where you can tell there's
     light/color/motion behind it without actually making out detail.
     "!important": WP core's own block-library CSS sets this element's
     background-color via ".has-featured-background-color { ... !important
     }" (core always marks preset color classes !important, to guarantee
     they win over theme styles) — ours has to match to be seen at all. */
  background-color: rgba(247, 242, 234, 0.88) !important;
  backdrop-filter: blur(5px) saturate(140%);
  -webkit-backdrop-filter: blur(5px) saturate(140%);
  transition: box-shadow var(--irz-transition), background-color var(--irz-transition);
}

body.irz-scrolled .superbthemes-navigation-three {
  padding-top: 12px !important;
  padding-bottom: 6px !important;
}

body.irz-scrolled .superbthemes-navigation-three > .wp-block-group {
  box-shadow: var(--irz-shadow-md);
}

/* Header layout: no "IRZ" wordmark — just navigation + the mail button.
   The logo column is removed from flow entirely (not just hidden text)
   so nav + button can take its place instead of leaving a dead gap.
   The three columns are the theme's own
   .superbthemes-navigation-three-columns-{logo,nav,button}; their
   flex-basis percentages are inline styles from the block editor, hence
   !important to actually override them. */
.superbthemes-navigation-three-columns-logo {
  display: none !important;
}

.superbthemes-navigation-three-columns-nav {
  flex-basis: 78% !important;
}

.superbthemes-navigation-three-columns-nav .wp-block-navigation {
  justify-content: flex-start !important;
}

.superbthemes-navigation-three-columns-button {
  flex-basis: 22% !important;
}

/* Animated underline on nav links */
.wp-block-navigation .wp-block-navigation-item__content {
  position: relative;
}

.wp-block-navigation .wp-block-navigation-item__content::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 100%;
  height: 1px;
  background: var(--irz-red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 300ms ease;
}

.wp-block-navigation .wp-block-navigation-item__content:hover::after,
.wp-block-navigation .wp-block-navigation-item.current-menu-item .wp-block-navigation-item__content::after {
  transform: scaleX(1);
}

/* ==========================================================================
   5. Buttons
   Applies to core buttons and Ultimate Addons for Gutenberg (uagb) buttons,
   so every button on the site — current and future — behaves consistently.
   !important on the transition is load-bearing: UAGB's own plugin CSS
   ships ".uagb-buttons__outer-wrap .uagb-buttons-repeater { transition:
   box-shadow .2s }" (2 classes) which otherwise beats our single-class
   selector's specificity and silently drops transform/color/etc from the
   transition — the visible symptom was hover feeling like an instant
   jump instead of an animation (the lift had no transition at all, only
   the shadow was ever fading).
   ========================================================================== */
.wp-element-button,
.wp-block-button__link,
.uagb-buttons-repeater {
  transition:
    transform var(--irz-transition-fast),
    box-shadow var(--irz-transition-fast),
    background-color var(--irz-transition),
    color var(--irz-transition),
    border-color var(--irz-transition) !important;
}

.wp-element-button:hover,
.wp-block-button__link:hover,
.uagb-buttons-repeater:hover {
  transform: translateY(-2px);
  box-shadow: var(--irz-shadow-sm);
}

.wp-element-button:active,
.wp-block-button__link:active,
.uagb-buttons-repeater:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Arrow icon (uagb buttons with an icon, e.g. "Kontaktiraj nas") glides right on hover */
.uagb-button__icon {
  display: inline-flex;
  transition: transform var(--irz-transition);
}

.uagb-buttons-repeater:hover .uagb-button__icon {
  transform: translateX(5px);
}

/* Text-only arrow links (e.g. "Pročitaj više", "Saznaj više →") */
.irz-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.irz-arrow-link::after {
  content: "\2192";
  display: inline-block;
  transition: transform var(--irz-transition);
}

.irz-arrow-link:hover::after {
  transform: translateX(5px);
}

/* ==========================================================================
   6. Cards
   ========================================================================== */
.irz-goal-card,
/* live: the 3 columns in "Naši ciljevi i planovi" */
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color {
  position: relative;
  overflow: hidden;
  transition: transform var(--irz-transition), box-shadow var(--irz-transition);
}

.irz-goal-card:hover,
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color:hover {
  transform: translateY(-6px);
  box-shadow: var(--irz-shadow-md);
}

.irz-goal-card::after,
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color::after {
  content: "";
  display: block;
  width: 32px;
  height: 2px;
  margin-top: var(--irz-space-sm);
  background: var(--irz-red);
  transition: width var(--irz-transition);
}

.irz-goal-card:hover::after,
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color:hover::after {
  width: 70px;
}

/* Goal card icons: gentle scale + tilt, never more than a few degrees */
.irz-goal-icon img,
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color figure img {
  transition: transform var(--irz-transition);
}

.irz-goal-icon:hover img,
.uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color:hover figure img {
  transform: scale(1.08) rotate(-3deg);
}

/* ==========================================================================
   7. Images
   ========================================================================== */

/* Generic opt-in premium hover — add "irz-image-hover" to a core Image block */
.irz-image-hover {
  overflow: hidden;
  border-radius: inherit;
}

.irz-image-hover img {
  transition: transform var(--irz-transition-slow);
}

.irz-image-hover:hover img {
  transform: scale(1.05);
}

/* Applied automatically to core (non-uagb) content images sitting inside an
   editorial split section — e.g. the images next to "Kako radimo?" and
   "Poziv na suradnju". Ultimate Addons images are left alone since they
   already carry their own configurable hover effect. */
.wp-block-group.has-mono-4-background-color:not(.column-parent-border-radius) figure.wp-block-image,
.wp-block-group.has-featured-background-color:not(.column-parent-border-radius) figure.wp-block-image {
  overflow: hidden;
}

.wp-block-group.has-mono-4-background-color:not(.column-parent-border-radius) figure.wp-block-image img,
.wp-block-group.has-featured-background-color:not(.column-parent-border-radius) figure.wp-block-image img {
  transition: transform var(--irz-transition-slow);
}

.wp-block-group.has-mono-4-background-color:not(.column-parent-border-radius) figure.wp-block-image:hover img,
.wp-block-group.has-featured-background-color:not(.column-parent-border-radius) figure.wp-block-image:hover img {
  transform: scale(1.045);
}

/* Fade-in for content images — auto-wired onto every core Image block's
   wrapping figure and every post-featured-image (see autoWireReveal() in
   irz-interactions.js §0), not just the two hand-picked split-section
   images this originally shipped with. Plain opacity 0 -> 1, deliberately:
   this used to be a clip-path wipe, but between this, the hero's
   slide-in, and the text reveals elsewhere, the page had too many
   different ways of "appearing" going on at once. A single consistent
   fade reads as calmer and more intentional. (It also sidesteps a real
   bug the wipe had: clip-path closing an element to zero visible width
   makes browsers report its OWN intersection ratio as permanently 0 no
   matter how far it scrolls into view, so — unlike opacity — it can be
   observed directly; see initReveal() in irz-interactions.js §1.)
   The opacity:0 starting state itself lives in the gated §1 rule above
   (".irz-js:not(.irz-reduced-motion) .irz-reveal-image:not(.is-visible)")
   rather than here unconditionally — this class is now applied broadly
   sitewide, so without JS (no ".irz-js" on <html>) or with reduced motion
   requested, every image must render normally from the first paint
   instead of staying invisible forever. */
.irz-reveal-image {
  transition: opacity 900ms var(--irz-ease-out);
}

.irz-reveal-image.is-visible,
.irz-reduced-motion .irz-reveal-image {
  opacity: 1;
}

/* ==========================================================================
   8. Scroll reveal system
   ========================================================================== */
.irz-reveal,
.irz-reveal-up {
  transform: translateY(30px);
}

.irz-reveal-left {
  transform: translateX(-30px);
}

.irz-reveal-right {
  transform: translateX(30px);
}

.irz-reveal-scale {
  transform: scale(0.94);
}

.irz-reveal,
.irz-reveal-up,
.irz-reveal-left,
.irz-reveal-right,
.irz-reveal-scale {
  transition: opacity 700ms var(--irz-ease-out), transform 700ms var(--irz-ease-out);
}

.irz-reveal.is-visible,
.irz-reveal-up.is-visible,
.irz-reveal-left.is-visible,
.irz-reveal-right.is-visible,
.irz-reveal-scale.is-visible {
  opacity: 1;
  transform: translate(0, 0) scale(1);
}

.irz-stagger-item {
  transform: translateY(24px);
  transition: opacity 700ms var(--irz-ease-out), transform 700ms var(--irz-ease-out);
}

.irz-stagger-item.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   9. Hero: geometry + entrance
   Targets the live hero row (logo + intro text): .uagb-block-a8c19914
   ========================================================================== */
.uagb-block-a8c19914 {
  position: relative;
  isolation: isolate;
  /* Not "hidden": the dot-grid canvas initDotGrid() inserts here (see
     irz-interactions.js §6) deliberately extends above and below this
     element's own box to also cover the header and the CTA buttons row
     (both separate sibling blocks) — an "overflow: hidden" here would
     clip that reach right back down to just this element. */
  overflow: visible;
}

/* Hero entrance stagger: logo, then text, then buttons.
   ":not(.irz-hero-in)" is load-bearing for the same reason as §1 — without
   it this rule ties in specificity with the "show it" rule below, and only
   keeps winning by accident of source order.
   The logo (a9b0d59e) fades in on opacity alone, no slide — it's a plain
   image, and pairing a slide with every other reveal on the page (the
   text/button slide right below, the mask-reveal images elsewhere) was
   more movement than the page needed. Text and buttons keep the slide. */
.irz-js:not(.irz-reduced-motion):not(.irz-hero-in) .uagb-block-a9b0d59e {
  opacity: 0;
  transition: opacity 800ms var(--irz-ease-out);
}

.irz-js:not(.irz-reduced-motion):not(.irz-hero-in) .uagb-block-ace22610,
.irz-js:not(.irz-reduced-motion):not(.irz-hero-in) .uagb-block-65cc9b7c {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 800ms var(--irz-ease-out), transform 800ms var(--irz-ease-out);
}

.irz-js.irz-hero-in .uagb-block-a9b0d59e { transition-delay: 0ms; }
.irz-js.irz-hero-in .uagb-block-ace22610 { transition-delay: 120ms; }
.irz-js.irz-hero-in .uagb-block-65cc9b7c { transition-delay: 240ms; }

.irz-js.irz-hero-in .uagb-block-a9b0d59e {
  opacity: 1;
}

.irz-js.irz-hero-in .uagb-block-ace22610,
.irz-js.irz-hero-in .uagb-block-65cc9b7c {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   10. Recent posts — editorial card polish for the "Nedavne objave" carousel

   Uses a real `border` for the hover ring rather than box-shadow. Box-
   shadow was tried first, but (a) the card has overflow:hidden from
   UAGB's own plugin CSS, which clips even an inset shadow's rendering
   in some browsers once a transition/inline-style fight is involved,
   and (b) a multi-layer box-shadow (ring + soft glow) doesn't always
   interpolate its two layers evenly mid-transition, which showed up as
   an uneven gap on the left/right edges. A border is a real box-edge
   property — always pixel-exact against the card's own edge, no
   interpolation ambiguity — and with box-sizing:border-box (already the
   case here) it doesn't shift layout when it appears.
   A translateY/scale lift isn't used: cards sit edge-to-edge with no
   gap, so any transform that grows the box overlaps the neighboring
   card, and with no explicit stacking order most of it rendered
   underneath its neighbor — the stray vertical line reported earlier.
   ========================================================================== */
.uagb-post__inner-wrap {
  /* Default transparent border reserves the space so hover doesn't shift
     layout; !important for the same UAGB-plugin-CSS-specificity issue as
     the buttons above. */
  border: 1px solid transparent !important;
  transition: border-color var(--irz-transition) !important;
}

.uagb-post__inner-wrap:hover {
  /* !important: this block's own UAGB "hover shadow" feature applies its
     (degenerate, all-zero) box-shadow via inline styles at hover-time
     (JS, not just CSS), which keeps reasserting itself over a plain
     rule here — !important is required to win against an inline style
     regardless of how it was set. */
  border-color: var(--irz-red) !important;
}

.uagb-post__inner-wrap .uagb-post__image,
.uagb-post__inner-wrap .uagb-post__image img {
  overflow: hidden;
  transition: transform var(--irz-transition-slow);
}

.uagb-post__inner-wrap:hover .uagb-post__image img {
  transform: scale(1.06);
}

.uagb-post__inner-wrap .uagb-post__title a {
  transition: color var(--irz-transition), transform var(--irz-transition);
  display: inline-block;
}

.uagb-post__inner-wrap:hover .uagb-post__title a {
  color: var(--irz-red);
  transform: translateX(3px);
}

.uagb-post__inner-wrap .uagb-post__cta a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.uagb-post__inner-wrap .uagb-post__cta a::after {
  content: "\2192";
  transition: transform var(--irz-transition);
}

.uagb-post__inner-wrap:hover .uagb-post__cta a::after {
  transform: translateX(5px);
}

/* ==========================================================================
   11. Subtle background texture (CSS-only, no image asset)
   ========================================================================== */
body {
  background-image:
    radial-gradient(circle at 1px 1px, rgba(0, 0, 0, 0.035) 1px, transparent 0);
  background-size: 3px 3px;
}

/* ==========================================================================
   12. Interactive dot-grid background
   Auto-wired by initDotGrid() (see irz-interactions.js §6) onto the hero
   row only (.uagb-block-a8c19914, logo + intro text) — kept to a single
   section deliberately, see the comment at initDotGrid() for why. The JS
   inserts a <canvas> as the section's first child and paints a grid of
   dots there that grow and slide away from the pointer.
   "isolation: isolate" is load-bearing, same technique as the hero's own
   decorative rings in §9 (which already had it for the same reason): it
   gives the section its own stacking context so the canvas's
   "z-index: -1" only tucks it behind THIS section's own content, instead
   of escaping to the nearest ancestor that already had a stacking
   context (which could be anywhere up the page, e.g. behind an unrelated
   section's background) — position:relative alone does not establish
   one.
   ========================================================================== */
.irz-dot-grid {
  position: relative;
  isolation: isolate;
}

.irz-dot-grid-canvas {
  /* left/width/top/height are set inline by initDotGrid() (see
     irz-interactions.js §6) — left and width deliberately span the full
     viewport rather than the section's own box, so the grid reaches
     edge-to-edge regardless of how narrow or padded the section is.
     max-width/margin here undo WordPress core's own
     ".is-layout-constrained > :where(...)" rule, which clamps every
     unmarked direct child of a constrained group (which is what the
     canvas, freshly inserted with no alignment class, otherwise looks
     like) down to the theme's content width and centers it — silently
     capping our explicit inline width back down to ~1200px regardless of
     what we set it to, since max-width always wins over width. Both
     "important" because that WP rule already is (its margins are
     "auto !important"), and its selector's ":where()" means beating it
     on plain specificity isn't reliable.
     "position" is "important" for a similar reason, but against a
     different rule: inside the hero (.uagb-block-a8c19914), Ultimate
     Addons for Gutenberg's own plugin CSS forces every unrecognised
     direct child of its container back to "position: relative" via a
     long chain of ":not(...)" clauses that, unlike ":where()", each add
     to the selector's specificity — comfortably beating our one class.
     Left as "relative", the canvas isn't taken out of flow at all, so
     its "left"/"top" become relative offsets from its normal in-flow
     position instead of an absolute placement — which, combined with
     the section's own left padding, was the exact source of a
     consistent 10px edge-to-edge offset in that section only. */
  position: absolute !important;
  z-index: -1;
  display: block;
  pointer-events: none;
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}

/* ==========================================================================
   13. Reduced motion + mobile
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .irz-reveal,
  .irz-reveal-up,
  .irz-reveal-left,
  .irz-reveal-right,
  .irz-reveal-scale,
  .irz-reveal-image,
  .irz-stagger-item,
  .irz-js .uagb-block-a9b0d59e,
  .irz-js .uagb-block-ace22610,
  .irz-js .uagb-block-65cc9b7c {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 768px) {
  .irz-goal-card:hover,
  .uagb-block-11896279 ~ .wp-block-columns .wp-block-column.has-mono-4-background-color:hover {
    transform: none;
  }

  .wp-element-button,
  .wp-block-button__link,
  .uagb-buttons-repeater {
    min-height: 44px;
  }
}

/* ==========================================================================
   14. Projects (archive-project.html + single-project.html)
   A project's own written content is expected to use the three classes
   below (added via Block -> Advanced -> Additional CSS class(es), same
   convention as "irz-section-label" etc. in §3) rather than any custom
   field — keeps a non-technical editor working entirely inside the
   normal block editor, matching how every other editorial extra in this
   theme already works.
   ========================================================================== */

/* The implementation-period line at the top of a project
   (e.g. "Provedba programa: lipanj – rujan 2026.") — a small red kicker,
   the same visual language as "irz-section-label" in §3. */
.irz-project-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 var(--irz-space-sm);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--irz-red);
}

.irz-project-meta::before {
  content: "";
  width: 16px;
  height: 1px;
  background: currentColor;
}

/* The one-line subtitle right under a project's title
   (e.g. "Medijska pismenost i odgovorno izvještavanje..."). */
.irz-project-lede {
  font-size: clamp(18px, 2vw, 22px);
  font-weight: 500;
  line-height: 1.4;
  color: var(--irz-text);
  margin: 0 0 var(--irz-space-md);
}

/* Funding/acknowledgment note closing out a project's content — set
   apart with a rule above it so it doesn't read as part of the last
   paragraph's own argument. */
.irz-project-funding {
  margin-top: var(--irz-space-lg);
  padding-top: var(--irz-space-md);
  border-top: 1px solid rgba(20, 56, 82, 0.1);
  font-size: 13px;
  font-style: italic;
  color: var(--irz-text-muted);
}

/* Reusable "arrow glides right on hover" link — the same treatment
   already used on the "Nedavne objave" cards (§10) via UAGB's own markup,
   generalized here into a plain class usable on any core link/button
   (not currently used by the pages below, kept available for future
   "read more"-style editorial links). */
.irz-link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  text-decoration: none;
}

.irz-link-arrow::after {
  content: "\2192";
  transition: transform var(--irz-transition);
}

.irz-link-arrow:hover::after {
  transform: translateX(5px);
}

/* "← Svi projekti"-style back link, single-project.html — the arrow is
   plain text in the link itself (not a pseudo-element) since it needs to
   read correctly even without CSS, so this only adds the hover glide,
   leftward to match the arrow's own direction. */
.irz-back-link {
  display: inline-flex;
  align-items: center;
  color: var(--irz-text-muted);
  font-weight: 600;
  text-decoration: none;
  transition: color var(--irz-transition-fast), transform var(--irz-transition-fast);
}

.irz-back-link:hover {
  color: var(--irz-red);
  transform: translateX(-3px);
}

/* Project archive cards reuse ".irz-goal-card" (§6) for the same hover
   lift + red underline accent as the homepage's goal cards — only the
   box itself (background/padding/radius, set via each block's own style
   panel in archive-project.html) is new here. */
.irz-project-card figure.wp-block-post-featured-image {
  overflow: hidden;
  margin: 0 0 var(--irz-space-sm);
}

.irz-project-card figure.wp-block-post-featured-image img {
  transition: transform var(--irz-transition-slow);
}

.irz-project-card:hover figure.wp-block-post-featured-image img {
  transform: scale(1.05);
}

/* Previous/next project navigation at the foot of a single project. */
.irz-project-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--irz-space-md);
  padding-top: var(--irz-space-lg);
  border-top: 1px solid rgba(20, 56, 82, 0.1);
}

.irz-project-nav .wp-block-post-navigation-link a {
  color: var(--irz-text);
  transition: color var(--irz-transition-fast);
}

.irz-project-nav .wp-block-post-navigation-link a:hover {
  color: var(--irz-red);
}

@media (max-width: 600px) {
  .irz-project-nav {
    flex-direction: column;
    gap: var(--irz-space-sm);
  }
}

/* The project archive's card grid — 3 columns down to 2 then 1, "!important"
   because Core's own Grid layout sets "grid-template-columns" as a plain
   class rule of the same specificity as this, so plain source order would
   make it a coin toss which one actually wins. */
.irz-project-grid {
  gap: var(--irz-space-md) !important;
}

@media (max-width: 900px) {
  .irz-project-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}

@media (max-width: 600px) {
  .irz-project-grid {
    grid-template-columns: 1fr !important;
  }
}
