/* ==========================================================================
   editorial.css — "Warm Architectural Editorial"
   Site-wide editorial-polish skin for home-ambient.si (Slovenian premium
   furniture retailer). A TOKEN + OVERRIDE layer over the vendored Inspiro /
   Bootstrap theme — loads AFTER theme.css / custom.css and wins by cascade.
   Plain CSS, no build step, no JS.

   The primary CTA is .ed-cta: a filled brand-gold button with a dark label. The
   render-board fork that used to live here (body.bt-ghost vs body.bt-bronze) was
   settled in favour of the fill; .ed-cta-ghost is the opt-in secondary.

   Accessibility notes baked into the palette (verified, not asserted):
     --ink   on --paper .... 13.8:1   (body/titles)
     --ink-2 on --paper ....  5.2:1   (secondary text — passes AA normal)
     --accent on --paper ...  3.5:1   (FAILS AA text; used as LINE/border ONLY)
     --ink on --btn-fill ...  5.35:1  (primary CTA — brand gold #AD9471 + dark label; passes AA)
   Consequence: brass (--accent) never carries small text; kicker / index /
   NOVO text is set in --ink. Brass appears only as rules, underlines, marks,
   focus ring and active states (all non-text, >=3:1).
   ========================================================================== */

:root {
  /* --- Paper & ink ------------------------------------------------------- */
  --paper:    #F4F1EA;   /* page ground */
  --paper-2:  #EDE8DE;   /* recessed panels / hairline fills */
  --ink:      #26241F;   /* primary text */
  --ink-2:    #6A6459;   /* secondary text */
  --charcoal: #2A2724;   /* warm dark — replaces theme cool slate #404859 */

  /* --- Accent (LINE ONLY) & button fill ---------------------------------- */
  --accent:   #9C7C3C;   /* brass — rules, underlines, marks, active states */
  --btn-fill: #AD9471;   /* brand gold (from the logo) — primary CTA fill; paired with dark --ink label */

  /* --- Hairlines --------------------------------------------------------- */
  --line:     rgba(38, 36, 31, 0.14);    /* on light */
  --line-2:   rgba(38, 36, 31, 0.28);    /* stronger divider */
  --line-inv: rgba(244, 241, 234, 0.20); /* on dark */

  /* --- Type scale -------------------------------------------------------- */
  --font-serif: "Newsreader", Georgia, "Times New Roman", serif;
  --font-sans:  "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --fs-display: clamp(2.75rem, 6vw, 5rem);
  --fs-h2:      clamp(1.6rem, 2.6vw, 2.1rem);
  --fs-h3:      clamp(1.02rem, 1.2vw, 1.18rem);
  --fs-kicker:  0.78rem;
  --fs-body:    1.0625rem;   /* 17px */
  --fs-small:   0.8125rem;   /* 13px */
  --lh-tight:   1.08;
  --lh-body:    1.5;

  /* --- Spacing scale (4 / 8 based) --------------------------------------- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;  --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;    --sp-7: 3rem;      --sp-8: 4rem;
  --sp-9: 6rem;     --sp-10: 8rem;

  /* --- Structure --------------------------------------------------------- */
  --maxw:      75rem;                              /* 1200px container */
  --gutter:    clamp(1.25rem, 5vw, 3rem);
  --section-y: clamp(4rem, 8vw, 8rem);             /* 64 -> 128px */

  /* --- Above-the-fold heights (hero + page-head band) ---------------------
     Tokens because each is read from more than one place and the pieces MUST move together:
     --hero-h drives the slider container AND the slide floor. See HERO and PAGE HEAD. */
  --hero-h:    68vh;
  --band-gap:  72px;                               /* clear space under the nav bar */
  --band-pb:   96px;                               /* the band's real height lever */
  --r-img:     0.1875rem;                          /* 3px — crisp, not bubbly */
  --tracked:   0.14em;                             /* signature kicker tracking */
  --dur:       0.28s;
  --ease:      cubic-bezier(0.22, 0.61, 0.36, 1);  /* ease-out */
}

/* ==========================================================================
   BASE
   ========================================================================== */
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.ed-container {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  width: 100%;
}

.ed-section { padding-block: var(--section-y); }

/* Give repeated sections an alternating warmth without a hard band */
.ed-section + .ed-section { border-top: 1px solid var(--line); }

/* Focus — brass ring (non-text 3.5:1 on light, 3.8:1 on dark) */
a:focus-visible,
.btn:focus-visible {
  outline: 0.14rem solid var(--accent);
  outline-offset: 0.2rem;
  border-radius: 0.06rem;
}

/* ==========================================================================
   SIGNATURE GRAMMAR
   tracked-caps kicker -> oversized LEFT-SET italic-serif title ->
   optional right-offset intro -> full-width brass hairline rule
   ========================================================================== */

/* Kicker: Poppins tracked-caps. Set in --ink-2 (5.2:1), NOT brass. */
.ed-eyebrow {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 var(--sp-4);
}
/* Over dark photography the kicker goes paper */
.ed-eyebrow-inv { color: var(--paper); }

/* Section header block — LEFT-SET, asymmetric (title left / action right),
   closed by a full-width BRASS hairline. Kills the theme's centered :before dash. */
.heading-text.heading-section.ed-section-head {
  display: grid;
  /* Column 2 is capped at the same measure .ed-section-intro declares, so an unbounded
     intro_text (references/models.py:54 -- a TextField, no max_length) can no longer eat
     the row. `auto` took the intro's max-content width, and .ed-section-intro is a <span>,
     so its own max-width was inert: measured "0px 1092px" at 1440, .ed-head-main width 0,
     <h2> width 0, bottom-aligned by align-items:end straight over the paragraph.
     fit-content() still lets the short .ed-link variant size to its own content. */
  grid-template-columns: minmax(0, 1fr) fit-content(34ch);
  align-items: end;
  gap: var(--sp-5);
  text-align: left;
  margin: 0 0 clamp(2.25rem, 4vw, 3.5rem);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--accent);   /* the brass signature rule */
}
.heading-text.heading-section.ed-section-head > .ed-head-main { grid-column: 1; }
.heading-text.heading-section.ed-section-head > .ed-head-action {
  grid-column: 2;
  justify-self: end;
  padding-bottom: 0.2rem;
}

/* The head already draws the brass rule that closes it (the border-bottom above). The
   action cell's .ed-link drew its own identical 1px brass border 17.8px higher (measured:
   0.2rem + var(--sp-4) + 1px) -- two parallel hairlines in the same colour and weight,
   which reads as a mistake rather than a system. The link keeps its border BOX, so hover
   costs zero layout shift; at rest the "->" from .ed-link::after plus the tracked caps
   carry the affordance. Scoped to the section head so the .ed-link in 404.html,
   search.html, product_list_page.html and reference_page.html keeps its underline. */
.heading-text.heading-section.ed-section-head .ed-link { border-bottom-color: transparent; }
.heading-text.heading-section.ed-section-head .ed-link:hover,
.heading-text.heading-section.ed-section-head .ed-link:focus-visible { border-bottom-color: var(--accent); }

/* Neutralize the theme's centered dash before H2 */
.heading-text.heading-section > h2:before {
  content: none !important;
  display: none !important;
}

/* Big section title — italic Newsreader display, left-set */
.heading-text.heading-section.ed-section-head h2 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: auto;
  font-size: var(--fs-h2);
  line-height: 1.12;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin: 0;
  text-align: left;
}

/* Optional right-offset intro (Poppins, narrow measure, secondary).
   display:block because this is a <span>: max-width is inert on a non-replaced inline box.
   Kept as a <span> rather than promoted to <p> in the templates -- style.css:4421
   `.heading-text.heading-section p { font-size:18px; font-weight:300 }` is (0,2,1) and
   would beat this rule, so the markup change makes it worse, not better. */
.ed-section-intro {
  display: block;
  max-width: 34ch;
  color: var(--ink-2);
  font-size: var(--fs-body);
  margin: 0;
}

/* ==========================================================================
   HEADER — transparent editorial bar over the hero
   ========================================================================== */
#header.ed-header[data-transparent="true"] {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 20;
  background: transparent;
}
.ed-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--sp-5);
  gap: var(--sp-6);
}
.ed-logo img { height: 2.5rem; width: auto; display: block; }
.ed-nav {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2.25rem);
  align-items: center;
}
.ed-nav a {
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper);
  text-decoration: none;
  padding-block: 0.35rem;
  position: relative;
}
/* active / hover — brass underline (line accent) */
.ed-nav a.is-active::after,
.ed-nav a:hover::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 0.11rem;
  background: var(--accent);
}

/* ==========================================================================
   HERO — .inspiro-slider.slider-fullscreen > .slide > .slide-captions
   ========================================================================== */
/* Hero height is on BOTH of these and must stay one value (--hero-h). The theme gives the
   container `height: 100vh` + `overflow: hidden` (style.css:1438) and every slide `height: 100%`
   (style.css:1444), so the container sets the height and the slide min-height is only a floor.
   A floor ABOVE the container clips the centred caption; BELOW it, page ground shows under the
   photo. (0,3,0) beats the vendored (0,2,0) and loads later. */
.ed-hero.inspiro-slider.slider-fullscreen {
  position: relative;
  height: var(--hero-h);
}
.ed-hero .slide {
  position: relative;
  min-height: var(--hero-h);
  background-size: cover;
  background-position: center 40%;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
  overflow: hidden;
}
/* Legibility scrim — LEFT-weighted (content is left-set). rgba = charcoal
   channels (42,39,36); top band darkens for the transparent nav. */
.ed-hero .slide::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(42, 39, 36, 0.55) 0%, rgba(42, 39, 36, 0) 22%),
    linear-gradient(90deg,
      rgba(42, 39, 36, 0.82) 0%,
      rgba(42, 39, 36, 0.55) 34%,
      rgba(42, 39, 36, 0.18) 66%,
      rgba(42, 39, 36, 0) 100%);
}

/* The theme pads this container 120/100px (style.css:1446) on top of the caption's own
   padding-block, and that stack is a height floor with teeth: functions.js:819-827 measures
   `.container` and, if it exceeds the window, writes `min-height: containerHeight + 100` INLINE
   onto the slider, every slide and the flickity viewport -- beating every stylesheet. The old
   numbers measured ~710px, so any viewport under ~720px tall silently re-inflated the hero and no
   CSS edit could shrink it. (0,3,0) ties the theme and loads later. */
.ed-hero .slide .container {
  padding-top: 0;
  padding-bottom: 0;
}
.ed-hero .slide-captions {
  position: relative;
  z-index: 2;
  /* Asymmetric on purpose: the top value clears the transparent 80px nav so the headline is
     optically centred in what the eye reads as the photo, not geometrically centred in the box. */
  padding-block: clamp(4rem, 8vh, 6rem) var(--sp-7);
  max-width: 46rem;
}
.ed-hero .ed-eyebrow {
  color: var(--paper);
  margin-bottom: var(--sp-5);
}
/* Hero headline — italic Newsreader display.
   Keyed on the class, not `h1.slide-title`: only the first slide is the page <h1>, the
   rest are <p> (see streams/main_header_block.html). */
.ed-hero .slide-title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: auto;
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  color: var(--paper);
  margin: 0 0 var(--sp-5);
  text-shadow: 0 0.06rem 1.6rem rgba(42, 39, 36, 0.35);
}
/* Theme parity for the slides that are NOT the page <h1>.

   This does not belong here on aesthetic grounds — it restates the vendored theme's own
   numbers — but the alternative is a hero whose second slide is body text. The theme
   styles the two elements separately and outranks the editorial layer on both:

     style.css:1450  .inspiro-slider .slide .slide-captions h1    (0,3,1)  80px/700
     style.css:1460  .inspiro-slider .slide .slide-captions > p   (0,3,1)  20px/400

   .ed-hero .slide-title is (0,2,0) and loses to each. So when slides 2+ became <p> to
   stop the page emitting one <h1> per slide, they silently dropped to 20px — measured,
   not inferred. Matching the theme's h1 values here keeps every slide identical to the
   hero the render board approved, rather than "fixing" slide 1 into something nobody
   has judged. Both breakpoints, because the theme splits them again below 992px.

   If the theme is ever unvendored, delete this block and let .ed-hero .slide-title win. */
body.ed .ed-hero .slide .slide-captions p.slide-title {
  font-size: 80px;
  font-weight: 700;
  line-height: 80px;
  margin-bottom: 30px;
}
@media (max-width: 991.98px) {
  body.ed .ed-hero .slide .slide-captions p.slide-title {
    font-size: 40px;
    line-height: 40px;
    margin-bottom: 14px;
  }
}
.ed-hero .ed-hero-sub {
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  line-height: 1.4;
  color: var(--paper);
  opacity: 0.92;
  margin: 0 0 var(--sp-7);
  max-width: 34ch;
}

/* Demoted promo — slim editorial footnote strip, NOT a shout banner */
.ed-hero .ed-promo {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--gutter);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
  background: rgba(42, 39, 36, 0.42);
  border-top: 1px solid var(--line-inv);
  backdrop-filter: saturate(1.1);
}
.ed-hero .ed-promo .ed-promo-mark {
  width: 0.5rem; height: 0.5rem;
  background: var(--accent);   /* brass mark — the one line-accent here */
  flex: none;
}

/* ==========================================================================
   BUTTONS — base + the V1/V2 fork
   Fixes the theme's white-on-gold primary (2.9:1 AA FAIL).
   ========================================================================== */
.btn.ed-cta,
a.btn.ed-cta:not([href]):not([tabindex]) {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  padding: 0.95rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
  text-decoration: none;
}
/* trailing arrow */
.btn.ed-cta::after {
  content: "\2192";   /* → */
  font-size: 1.05em;
  transition: transform var(--dur) var(--ease);
}
.btn.ed-cta:hover::after { transform: translateX(0.2rem); }

/* --- PRIMARY CTA (operator pick: filled brand gold, dark label) ---------
   Applies by DEFAULT — no body class. Brand gold #AD9471 fill + dark ink
   label ≈5.35:1 (white would be 2.9:1, fails AA). Same on light and on the
   dark hero (gold reads well over photography). */
.btn.ed-cta,
a.btn.ed-cta:not([href]):not([tabindex]),
.slide-captions .btn.ed-cta {
  background: var(--btn-fill);
  border-color: var(--btn-fill);
  color: var(--ink);
}
.btn.ed-cta:hover,
.btn.ed-cta:focus,
.slide-captions .btn.ed-cta:hover,
.slide-captions .btn.ed-cta:focus {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* --- SECONDARY CTA — opt-in ghost/outline via .ed-cta-ghost ------------- */
.btn.ed-cta.ed-cta-ghost {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}
.btn.ed-cta.ed-cta-ghost:hover,
.btn.ed-cta.ed-cta-ghost:focus {
  background: var(--ink);
  color: var(--paper);
}
.slide-captions .btn.ed-cta.ed-cta-ghost {
  background: transparent;
  border-color: var(--paper);
  color: var(--paper);
}
.slide-captions .btn.ed-cta.ed-cta-ghost:hover,
.slide-captions .btn.ed-cta.ed-cta-ghost:focus {
  background: var(--paper);
  color: var(--ink);
}

/* Tertiary read-more link (identical in both variants) — brass underline */
.ed-link {
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding-bottom: 0.2rem;
  border-bottom: 1px solid var(--accent);   /* brass line accent */
}
.ed-link::after {
  content: "\2192";
  transition: transform var(--dur) var(--ease);
}
.ed-link:hover { color: var(--ink-2); }
.ed-link:hover::after { transform: translateX(0.2rem); }

.ed-cta-row { margin-top: clamp(2.5rem, 4vw, 3.5rem); }

/* ==========================================================================
   CATEGORY TILES — .our-services .grid-layout.grid-2-columns > .grid-item
   Repeating set: zero-padded index via counter() (no markup change — the
   number is a ::before on the existing label element).
   ========================================================================== */
.our-services .grid-2-columns {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.25rem, 2.5vw, 2rem);
  align-items: start;
}
.our-services .grid-item { margin: 0; }
.our-services .grid-item > a {
  display: block;
  text-decoration: none;
  color: inherit;
}
.our-services .grid-item .img-fluid.rounded {
  width: 100%;
  aspect-ratio: 1 / 1;          /* uniform square crop -> tiles align cleanly */
  object-fit: cover;
  border-radius: var(--r-img);
  display: block;
  transition: transform 0.5s var(--ease);
}
.our-services .grid-item:hover .img-fluid.rounded { transform: scale(1.03); }

/* Caption: hairline rule, then the category name (NO index number). */
.our-services .ed-tile-cap {
  display: block;
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
/* Category name — Newsreader ROMAN, left-set */
.our-services .ed-tile-label {
  display: block;
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.2;
  color: var(--ink);
}

/* ==========================================================================
   PRODUCT CARDS — SCOPED to the catalog via .ed-products (added to the product
   list grid). This deliberately does NOT touch .reference-grid .product, so the
   references portfolio keeps its own approved design (references.css).
   ========================================================================== */
/* Real catalog markup: .shop > .grid-2-columns > .grid-item > .product.
   3-up inside the 9-col content area (the critic's 2->3 rec; 4-up is cramped
   next to the filter sidebar). */
.ed-products .grid-2-columns {
  display: grid;
  /* minmax(0, ...) and not a bare 1fr: `1fr` floors at MIN-CONTENT, so any unbreakable run in
     a card (the price carries white-space: nowrap so "od 4766,00 €" never splits) can push the
     tracks wider than the container and the grid overflows the viewport. Measured at 390px:
     tracks grew until the second column ran to x=425 on a 390px screen. Same reason .ed-cards
     is written this way. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
  align-items: start;
}
.ed-products .grid-item { margin: 0; width: auto; }
.ed-products .product { margin: 0; position: relative; }

.ed-products .product .product-image {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--r-img);
}
.ed-products .product .product-image img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  transition: transform 0.5s var(--ease);
}
.ed-products .product:hover .product-image img { transform: scale(1.03); }

/* KILL the theme's cyan/red badges -> warm caps chips over the photo (no cyan).
   APPEARANCE ONLY. Positioning is .ed-badge-stack's job. This block used to set
   `position: absolute` plus a per-flag `top` at (0,4,0), which out-specified
   `.ed-badge-stack > span { position: static }` at (0,1,1) -- so the flex column never
   laid a single chip out: measured 0x0 with every chip absolutely positioned inside it,
   17.5px apart against a 17.6px chip height, i.e. flush, gap never applied. */
.ed-products .product .product-image .product-new,
.ed-products .product .product-image .product-hot,
.ed-products .product .product-image .product-sale,
.ed-products .product .product-image .product-sale-off,
/* Aktualno's kind chip shares the appearance and differs only in tint -- see AKTUALNO. */
.ed-products .product .product-image .ed-update-kind {
  background: rgba(38, 36, 31, 0.86);
  color: var(--paper);
  border: 0;
  border-radius: 1px;
  font-family: var(--font-sans);
  /* 0.62rem was 8.68px at this project's 14px root -- below the floor at which tracked
     uppercase is legible, and the flags are the only thing on a card carrying merchandising
     information. --fs-small is the same token the price and the manufacturer kicker use, so
     the chips now sit on the card's existing type scale instead of under it. */
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  line-height: 1;
  padding: 0.4rem 0.65rem;
  white-space: nowrap;   /* keeps the Slovene space in "-56 %" from wrapping the chip */
}
.ed-products .product .product-image .product-sale-off {
  background: var(--accent);
  color: var(--ink);
}
.ed-products .product .product-overlay { display: none; }   /* drop theme quick-view */

/* Caption block (real wrapper is .product-description) */
.ed-products .product .product-description {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
/* Manufacturer kicker (NO index number) */
.ed-products .product .product-category {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  opacity: 1;
  margin: 0 0 var(--sp-2);
}
/* Product title — Newsreader ROMAN */
.ed-products .product .product-title { max-width: 100%; margin: 0; }
.ed-products .product .product-title h3 { margin: 0; }
.ed-products .product .product-title a,
.ed-products .product .product-title h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.22;
  color: var(--ink);
  text-decoration: none;
}
/* Price. The theme right-aligns this (a shop-SKU convention), which on a left-set card put
   the price on the opposite edge from the title it belongs to -- and wrapped the € onto its
   own line on any price over four digits. */
.ed-products .product .product-price {
  margin-top: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  color: var(--ink-2);
  text-align: left;
  /* text-align alone was not enough: the theme also floats this block right, so it kept
     starting ~100px in from the card's left edge with the label left-aligned inside it. */
  float: none;
  display: block;
  width: 100%;
}
.ed-products .product .product-price ins { text-decoration: none; color: var(--ink); }
/* margin-right moved to the `body.ed .product-price del` rule in SPECIFICITY REMEDIATION:
   setting only one side here left the theme's `margin: -20px 0 -4px` shorthand in charge
   of the other three, which is what pulled the old price up over the title. */
.ed-products .product .product-price del { color: var(--ink-2); opacity: 0.7; }

/* Flag stack: one flex column pinned to the top-left of the frame. Replaces four
   absolutely-positioned siblings that overlapped whenever a product carried two flags. */
.ed-badge-stack {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
}
/* The `position: static` reset that makes this stack work lives in the SPECIFICITY
   REMEDIATION section -- at (0,1,1) here it lost to the theme's (0,2,0). */

/* ==========================================================================
   BREADCRUMB — the way back, which the detail pages did not have
   ========================================================================== */
.ed-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  color: var(--ink-2);
  padding-block: clamp(1.5rem, 3vw, 2.5rem) 0;
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}
.ed-breadcrumb a { color: var(--ink-2); text-decoration: none; }
.ed-breadcrumb a:hover { color: var(--ink); border-bottom: 1px solid var(--accent); }
.ed-breadcrumb [aria-current="page"] { color: var(--ink); }
.ed-breadcrumb span[aria-hidden] { opacity: 0.45; }

/* ==========================================================================
   PRODUCT DETAIL
   ========================================================================== */
.ed-product { padding-bottom: var(--section-y); }
.ed-product-lead {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.ed-product-gallery .product,
.ed-product-gallery .product-image { margin: 0; position: relative; }
.ed-product-carousel { border-radius: var(--r-img); overflow: hidden; }
.ed-product-carousel img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
}

/* The information column: kicker -> serif title -> price -> one primary CTA -> facts */
.ed-product-info { padding-top: var(--sp-2); }
.ed-product-brand { margin-bottom: var(--sp-3); }
.ed-product-brand a.ed-eyebrow { text-decoration: none; }
.ed-product-brand a.ed-eyebrow:hover { color: var(--ink); }
.ed-product-title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: auto;
  font-size: clamp(2rem, 3.4vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 var(--sp-5);
}
.ed-product-price {
  font-family: var(--font-sans);
  font-size: 1.25rem;
  margin: 0 0 var(--sp-6);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--accent);
}
.ed-product-price ins { text-decoration: none; color: var(--ink); font-weight: 500; }
.ed-product-price del { color: var(--ink-2); opacity: 0.75; margin-right: var(--sp-3); }
/* Most of the catalogue has no price, so a priceless product renders no price row at all
   (operator's call at the render board). The brass rule that closed the price block then has
   to move down, or the CTA loses its divider on exactly those products. */
.ed-product-title + .ed-product-actions {
  padding-top: var(--sp-5);
  border-top: 1px solid var(--accent);
}
.ed-product-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-7);
}
/* Facts as a definition list: label above value, hairline-separated rows. */
.ed-product-meta { margin: 0; }
.ed-product-meta-row {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: var(--sp-4);
  padding-block: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-small);
}
.ed-product-meta-row:last-child { border-bottom: 1px solid var(--line); }
.ed-product-meta dt {
  margin: 0;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.ed-product-meta dd { margin: 0; color: var(--ink); }
.ed-product-meta dd a { color: var(--ink); border-bottom: 1px solid var(--accent); text-decoration: none; }
.ed-product-meta dd a:hover { color: var(--ink-2); }
.ed-product-brand-note {
  margin-top: var(--sp-6);
  padding-left: var(--sp-4);
  border-left: 1px solid var(--accent);
  color: var(--ink-2);
  font-size: var(--fs-small);
}
.ed-product-brand-note p { margin: 0; }

.ed-product-description,
.ed-product-related { padding-top: var(--section-y); }

@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  /* Brand, name and price come BEFORE the photographs on a phone.
     Operator's call at the 2026-07-27 gallery board: home-ambient is a premium brand judged
     "mostly on mobile", and what a visitor must not have to scroll for is which product this
     is and what it costs. Stacked in DOM order, a 25-photograph gallery pushed the <h1> and
     the price to ~672px — below the fold on any phone shorter than the 844px iPhone the board
     was shot on.

     display:contents unwraps the info column so its children become flex items of the lead
     and can be ordered around the gallery. Deliberately NOT a duplicated mobile-only header:
     that would emit a second <h1>. The DOM order is unchanged, so `.ed-product-title +
     .ed-product-actions` (the divider a priceless product depends on) still matches, and a
     screen reader still reads brand -> name -> price. Between 768 and 991 the lead is still
     two columns, so the price sits beside the photograph and none of this is needed. */
  .ed-product-lead {
    display: flex;
    flex-direction: column;
    grid-template-columns: 1fr;
    /* The lead's gap is a two-COLUMN gutter — clamp(2rem, 5vw, 4.5rem), 28px at 390px.
       Stacked, it landed between every line of type as well: brand->name measured 39px and
       name->price 48px, against 11px and 20px on desktop, so the header read as three
       unrelated blocks. The elements carry their own margins; the gutter is not one of them. */
    gap: 0;
    /* The base rule sets align-items:start, which is right for grid columns but in a COLUMN
       flex container means "size to content on the cross axis" -- and the gallery's content
       is a flickity slider with 25 inline-sized cells. Stretch is what the grid track did. */
    align-items: stretch;
  }
  /* A flex item defaults to min-width:auto, which is its MAX-CONTENT width -- and the
     gallery's max-content is 25 flickity cells laid side by side. Without this the frame
     blew out to several thousand pixels and the photograph overflowed the screen. The grid
     this replaced never had the problem because its track was already minmax(0, 1fr). */
  .ed-product-lead > * { min-width: 0; }
  .ed-product-info { display: contents; }
  .ed-product-brand { order: 1; }
  .ed-product-title { order: 2; }
  .ed-product-lead .product-price { order: 3; }
  .ed-product-gallery { order: 4; }
  .ed-product-actions { order: 5; }
  .ed-product-meta { order: 6; }
  .ed-product-brand-note { order: 7; }

  /* The price row closes itself with a brass rule, which directly above the photograph read
     as a divider belonging to the image rather than to the price. The gallery gets the
     breathing room instead. */
  .ed-product-lead .product-price {
    margin-bottom: 0;
    padding-bottom: var(--sp-4);
    border-bottom: 0;
  }
  .ed-product-gallery { margin-bottom: var(--sp-6); }
  /* Restores the divider the CTA row loses when the price stops drawing one. */
  .ed-product-actions { padding-top: var(--sp-5); border-top: 1px solid var(--accent); }

  .ed-product-meta-row { grid-template-columns: 1fr; gap: var(--sp-1); }
}

/* ==========================================================================
   PRODUCT GALLERY  —  "Spine"
   --------------------------------------------------------------------------
   Chosen at the 2026-07-27 render board over a filmstrip (A) and a no-carousel
   mosaic (C). The idea: the index is permanent and vertical, BESIDE the picture
   rather than under it, so "how much more is there" is answered without looking
   away from the photograph. It costs the hero ~5rem of width, which is the trade
   the board accepted.

   What this replaced, and why it had to go — the shipped carousel:
     - had 25 flickity page dots in the DOM and clipped every one of them with
       `overflow: hidden` on the wrapper, so a 25-photograph product rendered
       pixel-identically to a 1-photograph one;
     - set no `data-autoplay`, so it inherited the theme's autoPlay 7000 and
       rotated on its own while the visitor read;
     - exposed its prev/next only at `opacity: 0` until hover.

   Below 992px the spine unrolls into a horizontal strip under the frame; below
   768px the whole lead reorders so the name and price come first (see the
   PRODUCT DETAIL section above — operator's call, the phone is the primary
   surface for this brand).
   ========================================================================== */

.ed-gal {
  /* Local scale, so a breakpoint can retune the whole gallery in one place. */
  --gal-thumb:  5.5rem;    /* 77px — filmstrip cell (A) */
  --gal-spine:  5rem;      /* 70px — vertical rail (B) */
  --gal-ctrl:   2.75rem;   /* 38.5px — control chip; the WCAG 2.2 floor is 24px */
  --gal-gap:    var(--sp-2);
}

/* `.ed-product-gallery` is a grid item, so its automatic minimum size is its
   min-content — and a 25-cell filmstrip makes that 1568px. Measured at 390 before
   this line: the grid column was 330px wide and the gallery box 1568px, clipped by
   an ancestor rather than laid out, with the hero rendered ~4x the viewport.
   A grid item has to be told it may shrink; the strip's own `overflow-x: auto`
   does not do it. */
.ed-product-gallery { min-width: 0; }

.ed-gal-frame { position: relative; }
.ed-gal-main  { border-radius: var(--r-img); overflow: hidden; }
/* The cell images need width/aspect/object-fit, and
   `.ed-products .product .product-image img` (0,3,1) already sets exactly those.
   Nothing is restated here on purpose — a second copy at lower specificity would
   read as if it were doing something. */

/* --- Control chips: prev / next / full screen -----------------------------
   Square, hairline, ink — the same grammar as .ed-cta-ghost, which is where the
   site's outline-button language already lives. Deliberately NOT the theme's
   floating white circles, and deliberately not translucent: an --ink border on
   --paper is 13.8:1, so the control is identifiable against any photograph
   behind it (WCAG 1.4.11 asks 3:1). */
.ed-gal-arrow,
.ed-gal-zoom {
  width: var(--gal-ctrl);
  height: var(--gal-ctrl);
  display: grid;
  place-items: center;
  padding: 0;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
/* Scoped to .ed-gal so these reach (0,3,0). At (0,2,0) they tied with
   `.ed-gal .ed-gal-arrow { background: var(--paper) }` further down this file and lost on
   source order -- so hovering set color to --paper while the background STAYED --paper, and
   the chevron (fill:none, stroke:currentColor) vanished into an empty bordered square. */
.ed-gal .ed-gal-arrow:hover,
.ed-gal .ed-gal-arrow:focus-visible,
.ed-gal .ed-gal-zoom:hover,
.ed-gal .ed-gal-zoom:focus-visible { background: var(--ink); color: var(--paper); }
.ed-gal-arrow svg { width: 0.5rem;  height: 0.9rem; }
.ed-gal-zoom  svg { width: 0.95rem; height: 0.95rem; }
.ed-gal-arrows { display: flex; gap: var(--sp-2); }

/* --- Counter -------------------------------------------------------------
   The one number this page has never shown. Tabular figures so 9 -> 10 does not
   shift the slash, and the total is dropped to --ink-2 so the pair reads as
   "where you are" first and "how many" second. */
.ed-gal-counter {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  line-height: 1;
  color: var(--ink);
}
.ed-gal-slash { color: var(--ink-2); margin: 0 0.3em; }
.ed-gal-total { color: var(--ink-2); }

/* --- Shared thumbnail ----------------------------------------------------
   Emphasis by de-emphasis: the set is dimmed, the current photograph is not.
   State is carried by opacity AND a brass rule AND aria-current — never by
   colour alone. */
.ed-gal-thumb {
  display: block;
  width: 100%;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.ed-gal-thumb img {
  display: block;
  width: 100%;
  opacity: 0.62;
  transition: opacity var(--dur) var(--ease);
}
.ed-gal-thumb:hover img,
.ed-gal-thumb:focus-visible img,
.ed-gal-thumb.is-active img { opacity: 1; }

/* The catalogue card's hover-zoom is `.ed-products .product:hover .product-image img`
   (0,4,1), and the detail page carries body class `ed-products` — so hovering
   anywhere in the lead scaled all 25 thumbnails at once. (0,5,1) stops it on the
   rails; the hero keeps the zoom it already had. */
.ed-products .product:hover .ed-gal .ed-gal-thumb img { transform: none; }

/* ==========================================================================
   VARIANT B — "Spine"
   One idea: the index is permanent and vertical, beside the picture rather than
   under it, so "how much more is there" is answered without looking away.
   The trade the board is judging: the spine costs the hero 5rem of width.
   ========================================================================== */
.ed-gal-b-layout { position: relative; }
/* Keyed to the class the template only emits when there IS a spine. The spine itself is
   wrapped in {% if total > 1 %}, so an unconditional margin here reserved ~81px beside the
   photograph of every single-image product -- an empty gutter with the badge stack pushed
   into it. A class rather than :has() because the template already knows the answer. */
.ed-gal-has-spine .ed-gal-frame { margin-left: calc(var(--gal-spine) + var(--sp-3)); }

/* Absolute, not a grid column: 25 thumbnails are ~2000px of content, and a
   grid/flex track sized by that content would define the row height instead of
   the photograph. `inset-block: 0` pins the rail to exactly the frame's height
   whatever that turns out to be. */
.ed-gal-spine {
  position: absolute;
  inset-block: 0;
  left: 0;
  width: var(--gal-spine);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.ed-gal-spine-list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gal-gap);
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scroll-snap-type: y proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
.ed-gal-spine-list > li { flex: 0 0 auto; scroll-snap-align: start; }
.ed-gal .ed-gal-thumb {
  padding-left: var(--sp-1);
  border-left: 0.15rem solid transparent;   /* the mark runs along the spine's inner edge */
}
.ed-gal .ed-gal-thumb.is-active { border-left-color: var(--accent); }
.ed-gal-counter-spine {
  flex: 0 0 auto;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--accent);
  font-size: var(--fs-small);
}
/* B puts its controls ON the photograph, in one corner cluster — the explicit
   counterpart to A keeping them off it. */
.ed-gal-arrows-frame {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  z-index: 2;
}
.ed-gal .ed-gal-arrow { background: var(--paper); }

@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  /* B unrolls: the spine becomes a strip UNDER the frame. The spine precedes the
     frame in the DOM (it is the left rail on desktop), so the layout box has to
     reverse — without this the strip rendered above the photograph. The inner
     column-reverse then puts the counter above the strip, so B and A read in the
     same order on a phone. */
  .ed-gal-b-layout { display: flex; flex-direction: column-reverse; }
  .ed-gal-has-spine .ed-gal-frame { margin-left: 0; }
  .ed-gal-spine {
    position: static;
    width: auto;
    flex-direction: column-reverse;
    margin-top: var(--sp-4);
  }
  .ed-gal-spine-list {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
  }
  .ed-gal-spine-list > li { flex: 0 0 var(--gal-spine); }
  .ed-gal .ed-gal-thumb {
    padding-left: 0;
    padding-bottom: var(--sp-1);
    border-left: 0;
    border-bottom: 0.15rem solid transparent;
  }
  .ed-gal .ed-gal-thumb.is-active { border-bottom-color: var(--accent); }
  .ed-gal-counter-spine { padding-top: var(--sp-3); }
}

@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  .ed-gal { --gal-thumb: 4rem; --gal-spine: 4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ed-gal-thumb img,
  .ed-gal-arrow,
  .ed-gal-zoom { transition: none; }
  .ed-products .product:hover .ed-gal .ed-gal-main img { transform: none; }
}

/* ==========================================================================
   404
   ========================================================================== */
.ed-error { padding-block: var(--section-y); }
.ed-error-inner { max-width: 44ch; }
.ed-error-inner h1 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: auto;
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1.1;
  color: var(--ink);
  margin: 0 0 var(--sp-4);
}
.ed-error-inner p { color: var(--ink-2); margin: 0 0 var(--sp-6); }
.ed-error-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-bottom: var(--sp-7); }

/* ==========================================================================
   PAGE HEAD — the shared hero band (includes/page_head.html)
   Left-set, so it matches the section grammar instead of the theme's centred band.
   ========================================================================== */
/* Every selector here is written against `#page-title` rather than `.ed-page-head` alone:
   the theme styles this band by id, so a plain class selector at (0,1,0)-(0,2,0) loses to
   its (1,0,0)-(1,1,0) regardless of load order. Two things were being silently overridden:
   the band's own background, and text-align.

   The background matters more than it looks. The theme's #page-title is a NEARLY WHITE
   band (#fbfbfb) that the old per-template copies darkened by always emitting
   `<div class="bg-overlay">` -- a dark scrim -- whether or not there was a photo behind it.
   page_head.html only emits the scrim when there is actually an image to scrim, so without
   this rule the white .text-light <h1> landed on #fbfbfb at 1.04:1: the page heading was
   invisible on every template with no banner image set. */
body.ed #page-title.ed-page-head:not(.ed-page-head-photo) {
  background-color: var(--charcoal);
}
/* Band height. Replaces `body.ed #page-title.ed-page-head { padding-block: clamp(...) }`, DEAD
   since written: (1,2,1) against the theme's `#header[data-transparent] + #page-title` at
   (2,1,0), which wins whatever loads last. Measured before: 220/160px, 437px of visible band for
   an eyebrow and one word. This selector is the theme's own shape + body.ed = (2,3,1).

   The theme also sets `top: -120px; margin-bottom: -124px`, painting the band 120px above its
   flow position, so 40px (120 - the 80px header) is pulled off-screen. Net:
       visible = header(80) + gap-under-nav + content + padding-bottom
   `top` cancels out, so PADDING-BOTTOM is the lever. padding-top is written as 120px + the gap
   we want, because below the theme's 120px the eyebrow slides under the nav. Do not "simplify"
   the negative pair away -- it hides the band's top edge behind the transparent header. */
body.ed #header[data-transparent="true"] + #page-title.ed-page-head {
  padding-block: calc(120px + var(--band-gap)) var(--band-pb);
}
body.ed #page-title.ed-page-head .page-title {
  text-align: left;
  padding: 0;
  min-height: 0;
}
body.ed #page-title.ed-page-head .page-title h1 { margin: 0; }
body.ed #page-title.ed-page-head .page-title span.text-light {
  display: block;
  margin-top: var(--sp-4);
  max-width: 42ch;
  opacity: 0.86;
}
/* The theme splits this band again below 992px (style.css:113 -> `padding: 160px 0 80px`), so the
   tokens have to be restated here or the phone keeps the theme's numbers. Colocated with the rule
   they modify rather than filed in RESPONSIVE: the two are one decision. */
@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  :root {
    --band-gap: 40px;
    --band-pb: 56px;
  }
}

/* ==========================================================================
   FORMS — contact, product enquiry, search
   ========================================================================== */
.ed-field { margin-bottom: var(--sp-5); }
.ed-field label {
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}
/* The theme's asterisk was .text-danger (#e6335e) -- the loudest colour on the page, spent
   on "this field is required". Brass says the same thing in the palette's own voice. */
.ed-required { color: var(--accent); margin-left: 0.15em; }
.ed-field .form-control {
  border-radius: 1px;
  background: #fff;
  color: var(--ink);
  font-size: var(--fs-body);
  padding: 0.8rem 0.9rem;
}
/* help_text was .text-muted, which style.css sets to #6c757d at 4.0:1 on paper -- under the
   4.5:1 AA floor for the one piece of text that explains what to type. */
.ed-field-help {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-small);
  color: var(--ink-2);
}
.ed-field-error {
  margin-top: var(--sp-2);
  font-size: var(--fs-small);
  color: #8C2F2F;             /* 6.4:1 on paper; the theme's #e6335e is 3.4:1 */
  font-weight: 500;
}

/* ==========================================================================
   CONTACT
   ========================================================================== */
.ed-contact,
.ed-inquiry,
.ed-thanks,
.ed-generic,
.ed-taxonomy,
.ed-brands,
.ed-brand,
.ed-search { padding-block: var(--section-y); }

.ed-contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.ed-contact-intro { margin-bottom: var(--sp-6); color: var(--ink-2); }
.ed-contact-intro p:last-child { margin-bottom: 0; }
.ed-address-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--sp-6);
}
.ed-address { font-style: normal; margin: 0; font-size: var(--fs-small); line-height: 1.65; }
.ed-address-label {
  display: block;
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--accent);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  font-size: var(--fs-kicker);
  color: var(--ink-2);
}
.ed-address p { margin: 0 0 var(--sp-3); }
.ed-map { margin-top: var(--sp-7); border-radius: var(--r-img); overflow: hidden; }

.ed-inquiry-inner,
.ed-thanks-inner { max-width: 38rem; }
.ed-thanks-inner p { font-size: 1.15rem; color: var(--ink); }

@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  .ed-contact-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   TAXONOMY — category tiles reuse the homepage .our-services grammar
   ========================================================================== */
.our-services .ed-tile-note {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  color: var(--ink-2);
}
/* A category with no image keeps its slot instead of collapsing the tile. */
.ed-tile-placeholder {
  display: block;
  aspect-ratio: 1 / 1;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--r-img);
}
.ed-empty { color: var(--ink-2); font-style: italic; }

/* --- Brand grid ---------------------------------------------------------- */
/* The hairline grid is drawn by the tiles, not by painting a background through a 1px
   gap: with fewer brands than columns, auto-fill left empty tracks and that background
   rendered as a bare grey slab across the rest of the row. */
.ed-brand-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}
.ed-brand-grid > li { margin: 0; }
.ed-brand-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 7rem;
  padding: var(--sp-5);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-img);
  text-decoration: none;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
a.ed-brand-tile:hover { background: var(--paper-2); border-color: var(--accent); }
/* 4.5rem, not 3.5: plugins.css sets :root{font-size:14px}, so every rem on this site is
   87.5% of what it reads as, and 3.5rem capped these at 49px. */
.ed-brand-tile img { max-width: 100%; height: auto; max-height: 4.5rem; width: auto; }
/* A brand with no logo used to render an empty <li>: the slot was there, the brand was
   not, and there was nothing to click. */
.ed-brand-wordmark {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  color: var(--ink);
  text-align: center;
  line-height: 1.2;
}

/* --- Brand detail -------------------------------------------------------- */
.ed-brand-lead {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.ed-brand-lead:has(.ed-brand-intro:only-child) { grid-template-columns: minmax(0, 1fr); }
.ed-brand-logo { margin-bottom: var(--sp-6); }
.ed-brand-logo img { height: 3rem; width: auto; }
.ed-brand-copy p {
  margin: 0;
  font-size: var(--fs-body);
  color: var(--ink);
  line-height: 1.65;
}
.ed-brand-meta { margin-top: var(--sp-6); }
.ed-brand-gallery { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
.ed-brand-gallery img { width: 100%; height: auto; border-radius: var(--r-img); display: block; }
.ed-brand-cta { display: flex; justify-content: flex-start; }

@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  .ed-brand-lead { grid-template-columns: 1fr; }
}

/* ==========================================================================
   CATALOGUE — layout + the single filter panel
   ========================================================================== */
.ed-catalog { padding-block: var(--section-y); }
.ed-catalog-layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
.ed-catalog-main { min-width: 0; }

/* Desktop: no disclosure. The summary goes away and the panel is forced open, so the same
   markup that collapses on a phone is a plain sidebar here.
   `details > summary { display: none }` also removes the UA marker, and setting
   `display: block` on the body element overrides the UA's hiding of non-summary children
   -- verified in-page rather than assumed, because the mechanism differs between engines. */
@media (min-width: 992px) {  /* token-ok: layout breakpoint */
  .ed-filters-wrap > summary { display: none; }
  .ed-filters-wrap > .ed-filters-body { display: block; }
  /* Engines hide closed <details> content two different ways: older ones put display:none
     on the slot (which the rule above overrides), newer ones use
     `::details-content { content-visibility: hidden }` (which it does not). Both are
     covered; a browser that does not know this pseudo-element just skips the rule. */
  .ed-filters-wrap::details-content {
    content-visibility: visible;
    display: block;
  }
}

@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  .ed-catalog-layout { grid-template-columns: minmax(0, 1fr); }
  .ed-filters-wrap {
    border-block: 1px solid var(--line);
    margin-bottom: var(--sp-6);
  }
  .ed-filters-wrap > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-block: var(--sp-4);
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: var(--fs-small);
    font-weight: 600;
    letter-spacing: var(--tracked);
    text-transform: uppercase;
    color: var(--ink);
    list-style: none;
  }
  .ed-filters-wrap > summary::-webkit-details-marker { display: none; }
  .ed-filters-wrap > summary::after {
    content: "+";
    font-size: 1.2rem;
    line-height: 1;
    color: var(--accent);
  }
  .ed-filters-wrap[open] > summary::after { content: "\2212"; }  /* − */
  .ed-filters-wrap > .ed-filters-body { padding-bottom: var(--sp-5); }
}

.ed-filters .widget-title {
  font-family: var(--font-sans);
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  color: var(--ink-2);
  margin: var(--sp-6) 0 var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--accent);
}
.ed-filters .widget-title:first-of-type { margin-top: var(--sp-6); }
.ed-filters-clear { margin-bottom: var(--sp-5); }
.ed-filters-search label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.ed-filters-search .form-control { border-radius: 1px 0 0 1px; background: #fff; }
.ed-filters-search .btn.ed-cta { padding-inline: var(--sp-4); }
.ed-filters-search .btn.ed-cta::after { content: none; }   /* the arrow belongs on links, not on a search submit */

/* A compact variant of the CTA for in-panel controls */
.btn.ed-cta.ed-cta-sm { padding: 0.55rem 0.9rem; font-size: var(--fs-kicker); }
.btn.ed-cta.ed-cta-sm::after { content: none; }

/* Category / outlet filters: a hairline list, not a stack of shadowed pill buttons.
   The theme markup was `.btn.btn-light.btn-shadow.btn-rounded.btn-iconed` per row -- four
   button modifiers deep, and the active state added .active on top of .btn-light, so the
   "selected" filter was a rounded white pill next to identical rounded white pills. */
.ed-filter-list { list-style: none; margin: 0; padding: 0; }
.ed-filter-list > li { margin: 0; border-bottom: 1px solid var(--line); }
.ed-filter-list > li:first-child { border-top: 1px solid var(--line); }
.ed-filter-list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block: var(--sp-3);
  font-size: var(--fs-small);
  color: var(--ink);
  text-decoration: none;
}
.ed-filter-list a:hover { color: var(--ink-2); }
.ed-filter-list a .count { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.ed-filter-list a.active {
  font-weight: 600;
  box-shadow: inset 0.15rem 0 0 var(--accent);   /* brass edge marks the current filter */
  padding-left: var(--sp-4);
}
.ed-filter-list a.active .count { color: var(--ink); }

.ed-catalog-empty { color: var(--ink-2); }
.ed-catalog-empty p { margin-bottom: var(--sp-4); }
.ed-pagination { margin-top: var(--section-y); }

/* ==========================================================================
   SEARCH
   ========================================================================== */
.ed-search-form { max-width: 34rem; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.ed-search-form label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.ed-search-row { display: flex; gap: var(--sp-3); }
.ed-search-row .form-control { border-radius: 1px; background: #fff; padding: 0.8rem 0.9rem; }
.ed-search-count {
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--accent);
}
.ed-search-results { list-style: none; margin: 0 0 var(--sp-7); padding: 0; }
.ed-search-results > li { margin: 0; border-bottom: 1px solid var(--line); }
.ed-search-result {
  display: block;
  padding-block: var(--sp-5);
  text-decoration: none;
  transition: background var(--dur) var(--ease);
}
.ed-search-result:hover { background: var(--paper-2); }
.ed-search-result .ed-eyebrow { margin-bottom: var(--sp-2); }
.ed-search-result-title {
  display: block;
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: 1.35rem;
  line-height: 1.25;
  color: var(--ink);
}
.ed-search-result-desc {
  display: block;
  margin-top: var(--sp-2);
  max-width: 62ch;
  font-size: var(--fs-small);
  color: var(--ink-2);
}
.ed-search-empty { max-width: 42ch; }
.ed-search-empty p { color: var(--ink); }
.ed-search-empty-hint { color: var(--ink-2); font-size: var(--fs-small); }
.ed-search-suggestions {
  list-style: none;
  margin: var(--sp-5) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
}

/* ==========================================================================
   STREAMFIELD BLOCKS
   Every block used to open its own <section> with its own container and its own ad-hoc
   padding class (p-b-0, p-b-10, m-b-40), so vertical rhythm depended on which blocks an
   editor happened to stack. Blocks are plain .ed-block children of the host page's
   container now, and the rhythm is one rule.
   ========================================================================== */
.ed-block + .ed-block { margin-top: var(--section-y); }
.ed-block:first-child { margin-top: 0; }

/* A block-level band stays inside the host container. Full-bleeding out of a Bootstrap
   .container needs `margin-inline: calc(50% - 50vw)` plus `width: 100vw`, and 100vw counts
   the scrollbar -- which is a horizontal scroll on every desktop browser that shows one.
   Contained, with its own inset, is the version that cannot break the page. */
.ed-block-band {
  padding-inline: clamp(1.5rem, 4vw, 3rem);
}

/* Reading measure for rich text */
.ed-prose { max-width: 68ch; }
.ed-prose > :last-child { margin-bottom: 0; }
.ed-prose p { margin-bottom: var(--sp-5); }
.ed-prose h2, .ed-prose h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
}
.ed-lead {
  max-width: 60ch;
  font-size: 1.15rem;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
}
.ed-title-text .ed-lead { margin-top: calc(-1 * var(--sp-3)); }

/* --- Cards --------------------------------------------------------------- */
/* Fixed track counts, not `repeat(auto-fit, minmax(...))`. auto-fit stretches two items
   across the full width -- two "cards" a metre wide -- and auto-fill instead leaves empty
   tracks, which showed as bare grid background wherever a grid was painted through its gap.
   An explicit count leaves short rows left-aligned, which is what the grammar wants. */
.ed-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
/* The theme's .feature-box put every card on a white panel with a drop shadow. On a warm
   paper ground that reads as a floating UI widget, not as editorial content. */
.ed-card > a { display: block; text-decoration: none; color: inherit; }
.ed-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  border-radius: var(--r-img);
  transition: transform 0.5s var(--ease);
}
.ed-card > a { overflow: hidden; border-radius: var(--r-img); }
.ed-card > a:hover img { transform: scale(1.03); }
.ed-card-cap {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
.ed-card-cap h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.22;
  color: var(--ink);
  margin: 0;
}
.ed-card-cap p {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-small);
  color: var(--ink-2);
}
.ed-card-more {
  display: inline-block;
  margin-top: var(--sp-4);
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--accent);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}

/* --- Image & text -------------------------------------------------------- */
.ed-image-text {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.ed-image-text-media img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--r-img);
}
/* The only difference between the two variants: which column the picture sits in. */
.ed-image-right .ed-image-text-copy { order: 2; }
.ed-image-right .ed-image-text-media { order: 1; }
.ed-image-text:has(.ed-image-text-media:only-child) { grid-template-columns: minmax(0, 1fr); }

/* --- Numbered process ---------------------------------------------------- */
.ed-steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  border: 1px solid var(--line);
}
.ed-steps > li {
  counter-increment: step;
  margin: 0;
  padding: var(--sp-6) var(--sp-5);
  background: var(--paper);
  border-left: 1px solid var(--line);
}
.ed-steps > li:first-child { border-left: 0; }
.ed-steps > li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  margin-bottom: var(--sp-4);
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: var(--tracked);
  color: var(--accent);
}
.ed-steps h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  color: var(--ink);
  margin: 0 0 var(--sp-3);
}
.ed-steps p { margin: 0; font-size: var(--fs-small); color: var(--ink-2); }

/* --- Team / people ------------------------------------------------------- */
.ed-team-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.ed-team-member > a { display: block; text-decoration: none; color: inherit; }
.ed-team-member img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  border-radius: var(--r-img);
}
.ed-team-cap {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
.ed-team-cap .ed-eyebrow { margin-bottom: var(--sp-2); }
.ed-team-cap h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  color: var(--ink);
  margin: 0;
}
.ed-team-cap p { margin: var(--sp-3) 0 0; font-size: var(--fs-small); color: var(--ink-2); }

/* ==========================================================================
   REFERENCES — detail page + card typography
   references.css owns the index grid's layout; this brings its type and colour into the
   editorial palette (it was set in the theme's cool greys #8a8f98 / #6a6f78).
   ========================================================================== */
body.ed .reference-grid .product-title h3 a,
body.ed .reference-grid .product-title h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.22;
  color: var(--ink);
  text-decoration: none;
}
body.ed .reference-grid .product-description {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
body.ed .reference-grid .product-category {
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
}
body.ed .reference-tagline { color: var(--ink-2); font-size: var(--fs-small); }

.ed-reference { padding-bottom: var(--section-y); }
.ed-reference-lead {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.ed-reference-copy { max-width: 62ch; }
.ed-reference-copy > :last-child { margin-bottom: 0; }
.ed-reference-meta { padding-top: var(--sp-2); }
.ed-reference-gallery-wrap,
.ed-reference-products { padding-top: var(--section-y); }
.ed-reference-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}
.ed-reference-gallery img { width: 100%; height: auto; display: block; border-radius: var(--r-img); }
.ed-used-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.ed-used-item img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
  border-radius: var(--r-img);
}
.ed-used-cap {
  margin-top: var(--sp-4);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}
.ed-used-cap .ed-eyebrow { margin-bottom: var(--sp-2); }
.ed-used-cap h3 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 500;
  font-size: var(--fs-h3);
  color: var(--ink);
  margin: 0;
}
.ed-used-cap p { margin: var(--sp-3) 0 0; font-size: var(--fs-small); color: var(--ink-2); }

@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  .ed-image-text { grid-template-columns: 1fr; }
  .ed-image-right .ed-image-text-copy,
  .ed-image-right .ed-image-text-media { order: initial; }
  .ed-reference-lead { grid-template-columns: 1fr; }
  .ed-update-lead { grid-template-columns: 1fr; }
}

/* ==========================================================================
   AKTUALNO — news / promo / notice cards, and the item detail page
   ========================================================================== */
/* Grid, frame, chip appearance and caption type come from .ed-products, which both surfaces
   carry alongside .ed-updates. Only the deltas live here.

   This padding reaches the HOMEPAGE instance only: on /aktualno/ the section *is* #page-content,
   and the theme's `#page-content:not(.no-sidebar) { padding: 40px 0 }` (1,1,0) outranks a single
   class -- the same reason .ed-generic and .ed-catalog read like spacing rules but are not in
   charge. Deliberate: the listing then spaces like the catalogue beside it. */
.ed-updates { padding-block: var(--section-y); }

/* 4:3, not the catalogue's square: room and campaign photographs, and fill-1000x750 is the spec
   both surfaces request. (0,3,1) ties the .ed-products rule and wins on order. */
.ed-updates .product .product-image img { aspect-ratio: 4 / 3; }

/* Kind chip. Appearance is shared with the catalogue's flags (see PRODUCT CARDS); this only
   tints it. Every tint is DARK with --paper text: brass behind 13px text measures 3.8:1 and
   fails AA, so the kinds differ in hue, never lightness. --paper on each: 11.4 / 5.6 / 6.4:1. */
.ed-updates .product .product-image .ed-update-kind-promo { background: #7A5A22; }
.ed-updates .product .product-image .ed-update-kind-info  { background: #55504A; }

.ed-update-summary {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--ink-2);
}
/* The deadline is the one merchandising fact on a promo card, so it is set in --ink rather
   than the caption's --ink-2, with the label quiet beside it. */
.ed-update-valid {
  margin: var(--sp-2) 0 0;
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  color: var(--ink-2);
}
.ed-update-valid time { color: var(--ink); font-weight: 500; }

/* Item detail: lead photo beside the meta list, same 7/4 split the product page uses. */
.ed-update-lead {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
  margin-bottom: clamp(2.5rem, 6vw, 5rem);
}
.ed-update-lead-image {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-img);
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  .our-services .grid-2-columns,
  .ed-products .grid-2-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: clamp(1.75rem, 4vw, 2.5rem);
  }
  .ed-nav { display: none; }   /* real theme swaps in the burger menu here */

  .ed-cards,
  .ed-team-grid,
  .ed-used-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ed-brand-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ed-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* With two columns the left border has to reset on every odd cell, and the rows need a
     rule between them that the single-row desktop layout did not. */
  .ed-steps > li:nth-child(odd) { border-left: 0; }
  .ed-steps > li:nth-child(n + 3) { border-top: 1px solid var(--line); }
}

/* The section head stacks at 768, not 576. It used to rescue itself only below 575.98px,
   which is why the collapsed-column bug was "kinda ok on mobile" and broken on every
   tablet -- and tablet was never on a render board, so nobody saw it. 767.98 matches the
   boundary this file already uses at :701, :1367 and :1507. */
@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  .heading-text.heading-section.ed-section-head {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }
  .heading-text.heading-section.ed-section-head > .ed-head-action {
    grid-column: 1;
    justify-self: start;
  }
}

@media (max-width: 575.98px) {  /* token-ok: layout breakpoint */
  /* Was `.ed-hero .slide { min-height: 92vh }` -- 776px of an 844px phone, i.e. the hero WAS the
     phone's first screen. 92vh also explains why home_page.html's `data-height-xs="650"` did
     nothing: functions.js writes it as an inline `height`, which a taller min-height overrode.
     That attribute is gone, so the phone hero is CSS-governed like the desktop one. */
  :root { --hero-h: 66vh; }
  .ed-hero .slide-captions { max-width: 100%; }
  .ed-hero .slide-captions .ed-hero-sub { max-width: none; }

  .ed-cards,
  .ed-reference-gallery,
  .ed-steps { grid-template-columns: minmax(0, 1fr); }
  .ed-steps > li { border-left: 0; }
  .ed-steps > li + li { border-top: 1px solid var(--line); }
  .ed-brand-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Keep tiles/products two-up (never a lonely one-up scroll) at the small floor */
@media (max-width: 380px) {  /* token-ok: small-phone floor */
  .our-services .grid-2-columns,
  .ed-products .grid-2-columns { gap: var(--sp-4); }
}

/* ==========================================================================
   REDUCED MOTION — show resolved state, never freeze mid-transition
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
  }
  .our-services .grid-item:hover .img-fluid.rounded,
  .ed-products .product:hover .product-image img { transform: none; }
}

/* ==========================================================================
   REAL-THEME BINDINGS — hero page-title, header/nav, footer
   ========================================================================== */

/* Hero title band (references / generic / product-list) -> italic serif */
#page-title .page-title h1,
#page-title-logoheight .page-title h1 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.005em;
}
#page-title .page-title span.text-light,
#page-title-logoheight .page-title span.text-light {
  font-family: var(--font-sans);
}

/* --- Header / main menu (theme: #header #mainMenu nav > ul > li > a) ------ */
#header #mainMenu nav > ul > li > a {
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* wagtailmenus emits WAGTAILMENUS_ACTIVE_CLASS ("active") and ACTIVE_ANCESTOR_CLASS
   ("ancestor"), NOT the theme's `.current` -- measured in-page. Targeting only .current
   meant neither this layer nor the vendored theme ever marked the current page. */
#header #mainMenu nav > ul > li.active > a,
#header #mainMenu nav > ul > li.ancestor > a,
#header #mainMenu nav > ul > li.current > a,
#header #mainMenu nav > ul > li:hover > a,
#header #mainMenu nav > ul > li:focus > a { color: var(--accent); }
/* The logo was the theme's 80px everywhere, because the editorial layer's
   `#header #logo img { height: 2.4rem }` is (2,0,1) and style.css wins at (2,1,2) with
   `#header .header-inner #logo a > img, #header #header-wrap #logo a > img { height: 80px }`.
   Matching that selector exactly is what it takes to override it; anything shorter silently
   loses, which is how the 2.4rem sat in this file unapplied.

   At 80px the wordmark filled the 80px bar edge to edge with no air above or below it.
   4.5rem (63px) leaves ~8px top and bottom and reads as a mark placed in a bar rather than
   one wedged into it — 252x63 instead of 320x80. On a phone the same 80px was 296 wide,
   76% of a 390px screen; the 3.1rem below renders 174x43, 45%, and left-aligns it to the
   content gutter instead of the theme's centring. */
#header #logo img { width: auto; }
/* The bar centred the logo with `line-height: 80px` on #logo, which only works on an INLINE
   box -- and the img is display:block, so it escaped the line box and sat flush to the top.
   Invisible while the logo was 80px tall (it filled the bar); the moment it got shorter, all
   the slack fell below it. Flex on the anchor centres it exactly, at both breakpoints. */
#header #logo > a { display: flex; align-items: center; height: 100%; }
#header .header-inner #logo a > img,
#header #header-wrap #logo a > img { height: 4.5rem; }
@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  /* padding-bottom: 0 clears style.css:592's `padding-bottom: 6px`, which nothing else
     resets. With Bootstrap's global border-box that 6px came OUT of the declared height, so
     the wordmark rendered 6px shorter than the rule said and sat 3px above the optical
     centre of the flex-centred anchor.
     The height came DOWN from 3.5rem at the same time: 3.5rem only ever painted a 43px
     wordmark because of that padding, and 43px is the size the operator actually approved
     at the render board. Correcting the padding without correcting the height would have
     silently shipped a logo 14% larger than the one he signed off. */
  #header .header-inner #logo a > img,
  #header #header-wrap #logo a > img { height: 3.1rem; padding-bottom: 0; }

  /* The theme absolutely centres the mobile logo -- `#header #logo { position:absolute;
     width:100%; text-align:center; left:0 }` -- so the wordmark sat at x=123 while the
     breadcrumb, the <h1> and every other line on the page start at the 30px gutter. That is
     the same "centred on small, left-set on large" inconsistency the footer rules already
     undo, and it is the one thing in the header that does not obey the left-set grammar.
     30px is the theme's own mobile gutter (it uses the same number for
     .header-mobile-logo-left), not a new one. padding is !important on that rule, so the
     offset has to come from `left`. */
  #header #logo {
    width: auto;
    left: 30px;   /* token-ok: matches the theme's mobile container gutter */
    right: auto;
    text-align: left;
  }
}

/* --- Conversion band (footer CTA) ---------------------------------------- */
/* The band used to carry an inline `background-color:#404859` (the theme's cool slate),
   which this layer overrode via section[style*="404859"]. The markup now sets .ed-band
   instead, so the colour lives here rather than being an attribute-selector hack. */
.ed-band {
  background-color: var(--charcoal);
  color: var(--paper);
  padding-block: clamp(3rem, 5vw, 4.5rem);
}
.ed-cta-band-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
.ed-cta-band-copy { max-width: 34ch; }
.ed-cta-band-copy h2 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-optical-sizing: auto;
  font-size: var(--fs-h2);
  line-height: 1.12;
  letter-spacing: -0.005em;
  color: var(--paper);
  margin: 0;
  padding-top: var(--sp-5);
  border-top: 1px solid var(--accent);   /* the brass signature rule, inverted */
}
.ed-cta-band-copy p {
  margin: var(--sp-4) 0 0;
  color: var(--paper);
  opacity: 0.78;
  font-size: var(--fs-small);
}
.ed-cta-band-action { justify-self: end; }

@media (max-width: 767.98px) {  /* token-ok: layout breakpoint */
  .ed-cta-band-inner { grid-template-columns: 1fr; }
  .ed-cta-band-action { justify-self: start; }
  .ed-cta-band-copy { max-width: none; }
}

/* --- Footer -------------------------------------------------------------- */
#footer, #footer .footer-content { background: var(--paper); color: var(--ink); }
#footer { border-top: 1px solid var(--line); }
#footer a { color: var(--ink); }
#footer .widget-title {
  font-family: var(--font-sans);
  font-size: var(--fs-kicker);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  color: var(--ink-2);
}
#footer .copyright-content { border-top: 1px solid var(--line); color: var(--ink-2); }

/* ==========================================================================
   SPECIFICITY REMEDIATION  —  body.ed
   --------------------------------------------------------------------------
   Everything above this line was written assuming it wins on load order. It
   often does not. The vendored theme pads its selectors with :not(), and :not()
   contributes its argument's specificity, so theme rules land at (0,3,0)-(0,3,1)
   against this layer's (0,1,1)-(0,2,1) — and specificity is compared before
   source order. The rules below re-assert the ones that were being silently
   overridden, via the <body class="ed"> hook in base.html.

   Two notes for whoever touches this next:
   - @layer is NOT an option here: unlayered styles beat every layered style, so
     wrapping this file in a layer would make it lose to the entire theme.
   - `html body .btn.ed-cta` does NOT work either — it is (0,2,2), and the class
     column is compared before the element column, so it still loses to (0,3,x).
     The winning shape is to mirror the theme's own :not() chain and add body.ed.
   ========================================================================== */

/* --- Focus visibility (WCAG 2.4.7) --------------------------------------
   style.css:1414  a:not(.btn):not(.badge):focus { outline: none }        (0,3,1)
   style.css:4071  the same for .btn
   Result before this: no link or button on the site had a focus indicator.
   Mirroring the theme's chain gets us to (0,3,2) and wins. */
body.ed a:not(.btn):not(.badge):focus-visible,
body.ed .btn:not(.close):not(.mfp-close):focus-visible,
body.ed button:not(.close):not(.mfp-close):focus-visible,
body.ed input:not([type="hidden"]):focus-visible,
body.ed select:focus-visible,
body.ed textarea:focus-visible,
body.ed [tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 1px;
}

/* --- The paper ground ---------------------------------------------------
   style.css:14 (and again :6802)  section { background-color: #fff }
   painted over body{background:var(--paper)}, so the warm ground never reached
   any content area and --charcoal rendered nowhere on the site.
   .ed-white is the opt-out for full-bleed photography bands, .ed-band for the dark
   conversion band (which sets its own charcoal). */
body.ed section:not(.ed-white):not(.dark):not(.ed-band) {
  background-color: var(--paper);
}
body.ed section.ed-white { background-color: #fff; }

/* --- The bought theme's slate dash --------------------------------------
   The kill at :140 uses `> h2:before`, but the theme's rule is a *descendant*
   selector and the ported markup nests the h2 inside .ed-head-main — so a
   100x2px #404859 dash was still rendering ~10px under the new brass hairline.
   Match by descendant, and reclaim the 60px of bottom margin style.css:4413
   reserved for the dash it no longer draws. */
body.ed .heading-text.heading-section h2:before,
body.ed .heading-text.heading-section h2:after {
  content: none !important;
  display: none !important;
}
body.ed .heading-text.heading-section:not(.ed-section-head) h2 {
  margin-bottom: var(--sp-5);
}

/* --- Homepage service tiles --------------------------------------------
   :404 resets only `margin`, while the catalogue equivalent at :452 correctly
   resets `width` too — so these tiles kept the theme's float/width and rendered
   at half their grid track. */
body.ed .our-services .grid-item {
  margin: 0;
  width: auto;
  float: none;
  position: relative;
}
/* Give the scaling tile a clipping ancestor, as the product card already has,
   so the 1.03 hover does not bleed past the tile's own radius. */
body.ed .our-services .grid-item > a {
  display: block;
  overflow: hidden;
  border-radius: var(--r-img);
}

/* --- Primary CTA -------------------------------------------------------
   theme.css:48 / style.css:4109 reach (0,4,0)-(0,4,1) via :not() padding, so the
   gold fill + WHITE label (2.90:1, an AA failure) survived .ed-cta entirely
   wherever the markup also carried .btn-primary / .btn-light. */
body.ed .btn.ed-cta:not(.close):not(.mfp-close),
body.ed a.btn.ed-cta:not([href]):not([tabindex]) {
  background: var(--btn-fill);
  border-color: var(--btn-fill);
  color: var(--ink);
}
body.ed .btn.ed-cta:not(.close):not(.mfp-close):hover,
body.ed .btn.ed-cta:not(.close):not(.mfp-close):focus {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
/* The secondary needs the same treatment for the same reason: the fill rule above is
   (0,5,0), so the plain `.btn.ed-cta.ed-cta-ghost` at (0,3,0) lost and every "secondary"
   button rendered as a second gold primary -- two identical CTAs per view. */
body.ed .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close) {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}
body.ed .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close):hover,
body.ed .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close):focus {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
body.ed .slide-captions .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close) {
  border-color: var(--paper);
  color: var(--paper);
}
body.ed .slide-captions .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close):hover,
body.ed .slide-captions .btn.ed-cta.ed-cta-ghost:not(.close):not(.mfp-close):focus {
  background: var(--paper);
  color: var(--ink);
}

/* --- Footer links ------------------------------------------------------
   style.css:2265  #footer a:not(.btn):not(:hover) { color:#999 }  = 2.53:1.
   This block used to set --paper here, which was written for a dark footer and never
   revisited after the footer went to the paper ground: paper on paper is 1:1, so the
   whole Meni column and both social glyphs rendered invisible. --ink is 13.8:1. */
body.ed #footer a:not(.btn):not(:hover),
body.ed #footer a:not(.btn):not(:hover) i {
  color: var(--ink);
}
body.ed #footer a:not(.btn):hover { color: var(--ink-2); }
body.ed #footer .copyright-content {
  background: var(--paper-2);
  color: var(--ink);
}
body.ed #footer .copyright-content a { color: var(--ink); }

/* --- Interactive boundaries (WCAG 1.4.11) ------------------------------
   The theme's #e4e6ef borders sit at 1.25:1 on white — below the 3:1 required of
   a control boundary. --line/--line-2 cannot do this job either (1.32-1.78:1),
   so this is an opaque edge token: 4.06:1 on white, 3.60:1 on paper. */
body.ed {
  --edge: #8A857A;
}
body.ed .form-control,
body.ed .tags a,
body.ed .pagination .page-link {
  border-color: var(--edge);
}
/* The filter pills are theme buttons, so the winning rule is
   `.btn:not(.close):not(.mfp-close).btn-light` at (0,4,0) -- measured in-page, not
   guessed. Mirroring that chain and adding body.ed reaches (0,5,1). */
body.ed .btn:not(.close):not(.mfp-close).btn-light,
body.ed .btn:not(.close):not(.mfp-close).btn-white,
body.ed button.btn.btn-light,
body.ed a.btn.btn-light:not([href]):not([tabindex]) {
  border-color: var(--edge);
}
body.ed ::placeholder { color: var(--ink-2); opacity: 1; }
/* Manufacturer filters: the theme's .tags are fully-rounded shadowed pills, which next to
   the hairline category list read as two unrelated control systems on one panel. */
body.ed .ed-filters .tags a {
  border-radius: 1px;
  border-color: var(--edge);
  background: transparent;
  color: var(--ink);
  font-size: var(--fs-small);
  letter-spacing: 0.02em;
  box-shadow: none;
}
body.ed .ed-filters .tags a:hover { border-color: var(--accent); color: var(--ink); }
body.ed .ed-filters .tags a.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
/* The active pagination chip is the only "you are here" signal on the catalogue. */
body.ed .pagination .page-item.active .page-link {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* --- Footer: editorial rhythm -------------------------------------------
   Four columns of settings-driven content that the theme centred on small screens and
   left-set on large, mid-paragraph. Left-set everywhere, on one measure. */
body.ed #footer {
  border-top: 1px solid var(--accent);   /* brass rule closes the page */
}
body.ed #footer .footer-content { padding-block: clamp(2.75rem, 5vw, 4rem); }
/* float:none also clears style.css:2464, which floats EVERY footer widget out of its own
   Bootstrap column below 992px -- the same containment bug one column over. */
body.ed #footer .widget { text-align: left; margin-bottom: var(--sp-5); float: none; }
body.ed #footer .widget-title { margin-bottom: var(--sp-4); }
body.ed #footer .widget p,
body.ed #footer .widget div { font-size: var(--fs-small); line-height: 1.65; }
body.ed #footer .widget p:last-child { margin-bottom: 0; }
body.ed .ed-footer-address { display: block; margin-bottom: var(--sp-4); }
body.ed .ed-footer-address:hover { color: var(--ink-2); }
body.ed .ed-footer-nav a { display: block; padding-block: 0.2rem; }
body.ed .ed-footer-nav a:hover { border-bottom: 0; color: var(--ink-2); }
body.ed .ed-footer-logo { display: block; margin-top: var(--sp-5); }
body.ed .ed-footer-logo img { width: 8.75rem; height: auto; }
/* Social: square chips with a real 3:1 boundary instead of the theme's #d7d7d7 (1.28:1).
   style.css:4516 sets .social-icons{line-height:0}, :4522 .social-icons li{float:left} and
   :4524 .social-icons li a{float:left; margin:0 4px 4px 0}. Nothing cleared those floats and
   nothing established a BFC, so .ed-footer-social computed height:0 and the logo below it
   rendered BESIDE the icons instead of under them -- indented by exactly the icon row
   (measured +72px = 2 x 36px, at both 1440 and 390). A flex row contains its items by
   construction, at every breakpoint, and puts the gap on a token. */
body.ed .ed-footer-social ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
body.ed .ed-footer-social li { float: none; list-style: none; }
/* display is load-bearing, not decoration. Dropping the theme's `float: left` (above) left
   the anchor `display: inline`, and an inline box ignores width/height -- so the theme's
   32x32 chip collapsed and the border shrink-wrapped the glyph into a 12x24.5px sliver.
   inline-flex restores the box AND centres the icon in it without relying on the theme's
   line-height trick. Sizing still comes from style.css:4524. */
body.ed .ed-footer-social li a {
  float: none;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
body.ed .ed-footer-social li a {
  border: 1px solid var(--edge);
  border-radius: 1px;
  color: var(--ink);
}
body.ed .ed-footer-social li a:hover {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--paper);
}
body.ed #footer .copyright-content { padding-block: var(--sp-5); }
body.ed #footer .copyright-text { text-align: center; font-size: var(--fs-small); }
body.ed #footer .copyright-text p { margin: 0; }

/* --- Header: the bar needs a ground on every page that has no hero -------
   includes/header.html hard-codes data-transparent="true", so the theme leaves
   .header-inner at rgba(0,0,0,0) everywhere. That is right on the homepage, where the
   bar sits over the hero photograph -- and wrong on the other twenty-odd templates,
   where a WHITE logo and WHITE nav labels landed on the paper ground at about 1.05:1.
   The site's primary navigation was effectively invisible above the fold on every page
   except the homepage. home_page.html opts into the transparent treatment with
   .ed-has-hero; everything else gets the charcoal bar (white on charcoal = 13.1:1).

   Specificity, measured rather than assumed: the rule that actually wins is
   `#header.dark[data-transparent="true"]:not(.sticky-active) .header-inner` at (1,4,0) --
   a plain `body.ed:not(.ed-has-hero) #header .header-inner` is only (1,3,1) and lost. So
   mirror the theme's whole chain and add the body hook, which lands at (1,6,1).
   :not(.sticky-active) is kept deliberately: once the page scrolls, the theme adds that
   class and paints its own opaque bar, and this should not fight it. */
body.ed:not(.ed-has-hero) #header.dark[data-transparent="true"]:not(.sticky-active) .header-inner,
body.ed:not(.ed-has-hero) #header.dark[data-transparent="true"]:not(.sticky-active) #header-wrap {
  background-color: var(--charcoal);
}

/* --- Header nav: the "you are here" mark --------------------------------
   editorial.css only recoloured li.current > a, and brass text on the dark bar is the
   weakest possible signal -- brass on charcoal is 3.1:1, an AA failure for text. The
   label stays paper and the brass does what brass does everywhere else in this layer:
   it draws a line. */
body.ed #header #mainMenu nav > ul > li > a { position: relative; }
body.ed #header #mainMenu nav > ul > li.active > a,
body.ed #header #mainMenu nav > ul > li.ancestor > a,
body.ed #header #mainMenu nav > ul > li.current > a,
body.ed #header #mainMenu nav > ul > li:hover > a { color: var(--paper); }
body.ed #header #mainMenu nav > ul > li.active > a::after,
body.ed #header #mainMenu nav > ul > li.ancestor > a::after,
body.ed #header #mainMenu nav > ul > li.current > a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.55rem;
  height: 0.11rem;
  background: var(--accent);
}

/* --- Badge stack -------------------------------------------------------
   style.css:2104 and :2114 position every flag `absolute` at (0,2,0) -- including
   `bottom: 0` on .product-sale-off, which NO layer ever reset. Measured on a live outlet
   card: top 10.5px / bottom 0 / height 255.5px -- a 45px-wide brass column down the whole
   photo, carrying 8.68px text. `.ed-badge-stack > span` was (0,1,1) and lost both to the
   theme and to this layer's own (0,4,0) appearance block, so the stack has never laid out
   a single chip. (0,2,1) clears the theme, and the appearance block no longer positions,
   so nothing outranks this. */
body.ed .ed-badge-stack > span {
  position: static;
  top: auto;
  right: auto;
  bottom: auto;
  left: auto;
}

/* --- Product badges ----------------------------------------------------
   style.css:2104 gives these a 42x42 box with line-height:42px, which this layer
   never reset — so tiny labels sat crammed at the top of a dark square and two
   flags on one product overlapped by ~24px. */
body.ed .product .product-new,
body.ed .product .product-hot,
body.ed .product .product-sale,
body.ed .product .product-sale-off {
  width: auto;
  height: auto;
  line-height: 1;
  right: auto;
  /* Kept in step with the .ed-products block above deliberately: two different chip sizes
     on two surfaces is how the 0.62 / 0.6875 split happened in the first place, and only the
     smaller one was ever visible because it out-specified this one. */
  padding: 0.4rem 0.65rem;
  font-size: var(--fs-small);
  border-radius: 1px;
  /* The warm chip colours were only ever set under .ed-products, which is the catalogue
     grid scope -- so on the product DETAIL page the same flags kept the theme's cyan and
     crimson (#00c0e4 / #e6335e), the two loudest colours on the site, against a warm
     paper ground. These are the palette-wide defaults; .ed-products still positions them. */
  background: rgba(38, 36, 31, 0.86);
  color: var(--paper);
  border: 0;
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: var(--tracked);
  text-transform: uppercase;
  /* Two more the theme sets at :2104/:2114 and this layer never reset: a drop shadow
     from the era when these were 42px circles, and center alignment that is wrong once
     the box is shrink-to-fit. */
  text-shadow: none;
  text-align: left;
  white-space: nowrap;
}
body.ed .product .product-sale-off {
  background: var(--accent);
  color: var(--ink);
}

/* --- Old price ---------------------------------------------------------
   style.css:2098 `.product .product-price del` (0,2,1) sets
   { display:block; font-size:12px; margin:-20px 0 -4px; opacity:.6 }.
   :575 below set only margin-RIGHT, so the theme's shorthand survived as
   `-20px 5.6px -4px 0` (measured), and .ed-product-price del (0,1,1) lost outright.
   A block-level <del> pulled 20px up overlapped the card's <h3> by 13px at 390px and
   pushed into the detail <h1>'s gap. The old price belongs on the same line as the new
   one -- which is exactly what :575's margin-right was written for. (0,2,2) clears the
   theme on BOTH surfaces with one rule.
   nowrap also settles the "€ wraps onto its own line" note at :559: at 2-up/390px a card
   is ~165px, and "od 4766,00 €" breaks after "od" without it. */
/* Two selectors, both deliberately specific enough: the card's own
   `.ed-products .product .product-price { display: block }` is (0,3,0), so (0,3,1) is the
   floor on the catalogue side, and the detail page's price is not inside a .product at all. */
body.ed .product .product-price,
body.ed .ed-product-price {
  /* A wrapping flex row, not a run of inline boxes. At 2-up on a 390px screen a card is
     156px, and "od 3200,00 €" + "od 2560,00 €" cannot share a line -- as inlines they wrapped
     visually but the block kept a one-line height (26px against 198px of content), so the old
     price spilled out of its own box. As flex items they wrap AND the row grows.
     column-gap replaces the margin-right that used to separate them. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--sp-2);
  row-gap: 0.15rem;
}
body.ed .product-price del {
  display: inline;
  margin: 0;
  /* Never break a price mid-number ("od 4766,00 €" split after "od"); the flex row above is
     what lets the two prices fall onto separate lines instead. */
  white-space: nowrap;
}
body.ed .product-price ins { white-space: nowrap; }

/* --- The hero below 992px ----------------------------------------------
   Two things were wrong on every phone and tablet, and both were invisible from the
   desktop renders the direction was approved on:

   1. style.css:  @media (max-width: 991.98px) { .inspiro-slider .slide .slide-captions
      { text-align: center } }.  The left-set kicker -> serif headline -> CTA is THE
      signature of this direction, and mobile had never once rendered it. Measured, not
      guessed: the caption computed `center` at 390px.

   2. Flickity's prev/next buttons are 78x78 and sit at y 302-380, while the <h1> occupies
      y 322-402 -- the "next" arrow landed on top of the headline's last line, 58px into it.
      The slider keeps its dots and its swipe gesture, so the arrows are the part that goes.
   ---------------------------------------------------------------------- */
@media (max-width: 991.98px) {  /* token-ok: layout breakpoint */
  body.ed .ed-hero.inspiro-slider .slide .slide-captions {
    text-align: left;
  }
  body.ed .ed-hero .flickity-prev-next-button { display: none; }
}

/* --- data-animate failsafe ---------------------------------------------
   style.css:6643 [data-animate]{opacity:0}, and `.visible` is only ever added by
   jQuery Waypoints — which functions.js skips entirely if Waypoint is undefined.
   That gates the <h1> of nine templates, including the homepage hero and its LCP
   element, on third-party JS succeeding. It reliably renders blank in headless
   capture, which is the same failure a real visitor sees if that JS does not load.

   CSS alone cannot fix this: the failure case is "JS ran but Waypoints was absent",
   so an html.no-js hook would already have been removed. The actual guarantee is
   the timeout in base.html, which reveals anything still un-revealed. This block
   only handles reduced-motion, where no reveal animation should run at all.

   Deliberately NOT `opacity:1 !important` — that outranks the animation's own
   declarations and degrades the fade into a translate-only slide. */
@media (prefers-reduced-motion: reduce) {
  body.ed [data-animate] { opacity: 1; }
}
