/* ==========================================================================
   iWON Design System
   Translated from the approved mockups:
     - iwon-homepage-full.html
     - iwon-service-page-template.html (+ v2 additions)

   Scoping note: every rule that paints something is scoped under `.iwon-page`
   (added to <body> only by iWON page templates). Tokens live on :root because
   custom properties alone render nothing and are safe to expose globally.
   This is what lets the new design coexist with the legacy WPBakery pages.
   ========================================================================== */

:root {
  /* Surface */
  --iwon-bg:           #0A0D10;
  --iwon-border:       #15181D; /* nav / footer rules */
  --iwon-border-2:     #1B1F25; /* section dividers */
  --iwon-border-3:     #2A2F36; /* ghost button */

  /* Text */
  --iwon-text:         #EDEFF2;
  --iwon-text-nav:     #B7BEC6;
  --iwon-text-muted:   #9AA3AD;
  --iwon-text-dim:     #8A9199;
  --iwon-text-dimmer:  #6B7480;
  --iwon-text-faint:   #5B6470;
  --iwon-text-proof:   #7C8590;

  /* Brand */
  --iwon-blue:         #2D6CDF; /* primary action */
  --iwon-blue-light:   #4C8CF5; /* accent / logo mark */
  --iwon-blue-lighter: #8AB4FF; /* gradient terminus */
  --iwon-amber:        #F2A93B; /* eyebrow, featured, proof dot */

  /* Type */
  --iwon-font-display: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  --iwon-font-mono:    'IBM Plex Mono', 'SF Mono', Menlo, monospace;
  --iwon-font-body:    'Inter', -apple-system, 'Segoe UI', sans-serif;

  /* Glass panel */
  --iwon-glass-bg:     rgba(255, 255, 255, 0.025);
  --iwon-glass-border: rgba(255, 255, 255, 0.08);
  --iwon-glass-blur:   blur(10px);

  /* Layout */
  --iwon-gutter:       7vw;
  --iwon-radius:       10px;
  --iwon-radius-sm:    4px;

  /* Long-form reading (blog)
   *
   * The system had no body-copy tone before the blog, because until then no
   * page carried more than a paragraph or two at a time — everything was
   * headings, card descriptions and short intros, all of which are deliberately
   * dimmed. Running 1,500 words of --iwon-text-dim (#8A9199, 5.0:1) is a
   * different job: it reads as greyed-out rather than as text. This sits
   * between --iwon-text and --iwon-text-nav at 10.6:1 on --iwon-bg, which is
   * comfortable for sustained reading without competing with the headings.
   */
  --iwon-text-read:    #BFC6CE;

  /* Measure for the article column. 740px lands at roughly 75 characters at
     the 17px body size below — the middle of the 60-80 range — and matches the
     720px cap the page hero already uses closely enough that the hero and the
     first paragraph share a left edge and read as one column. */
  --iwon-read-width:   740px;

  /*
   * Backing colour painted behind post images. See the .iwon-article img rule
   * for why this exists and why it is safe on opaque images.
   */
  --iwon-img-backing:  #EDEFF2;
}

/* --------------------------------------------------------------------------
   Base / global dark treatment
   -------------------------------------------------------------------------- */

body.iwon-page {
  background: var(--iwon-bg);
  color: var(--iwon-text);
  font-family: var(--iwon-font-body);

  /*
   * `hidden` clips visually but leaves the box scrollable programmatically,
   * and it propagates to the viewport rather than clipping this element's own
   * descendants. The drifting wash below is an absolutely positioned
   * descendant, so under `hidden` it grew the document to 1556px on a 1440px
   * viewport — measured, not assumed. `clip` clips here and creates no scroll
   * container at all. `hidden` is kept first as the fallback for browsers that
   * do not understand `clip`.
   */
  overflow-x: hidden;
  overflow-x: clip;
}

/* Ambient background wash.
 *
 * The two-point radial wash used to sit in body's `background` shorthand.
 * It now lives on a pseudo-element for one reason: so the slow ambient drift
 * can animate `transform`, which the compositor handles on its own thread.
 * Animating `background-position` on a full-page gradient would repaint the
 * whole document every frame, which is exactly the jank this is meant to avoid.
 *
 * Still absolutely positioned rather than fixed, and still anchored to the top
 * of the document — the mockups deliberately let the wash scroll away instead
 * of following the viewport, and that behaviour is unchanged.
 *
 * The homepage keeps the mockup's values via the --gradient modifier. Interior
 * pages, which the mockups left flat, get a much fainter version of the same
 * treatment: enough to stop them reading as dead space, not enough to notice.
 */
body.iwon-page { position: relative; }

body.iwon-page::before {
  content: '';
  position: absolute;
  top: 0;
  /* Flush to the box, not inset negatively — combined with the reduced scale
     below this keeps the drift almost entirely inside the element, so the
     `overflow-x: clip` above is a safety net rather than load-bearing. */
  left: 0;
  right: 0;
  height: 1100px;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 880px 460px at 22% 0%, rgba(45, 108, 223, 0.075), transparent 62%),
    radial-gradient(ellipse 620px 420px at 86% 6%, rgba(242, 169, 59, 0.038), transparent 62%);
  animation: iwon-wash-drift 28s ease-in-out infinite alternate;
}

body.iwon-page.iwon-page--gradient::before {
  height: 1400px;
  background:
    radial-gradient(ellipse 900px 500px at 15% 0%, rgba(45, 108, 223, 0.16), transparent 60%),
    radial-gradient(ellipse 700px 500px at 90% 10%, rgba(242, 169, 59, 0.10), transparent 60%);
}

/* Roughly a 28s round trip, a couple of percent of travel. Deliberately below
   the threshold where you would catch it moving if you looked directly at it. */
@keyframes iwon-wash-drift {
  from { transform: translate3d(-1.2%, 0, 0) scale(1); }
  to   { transform: translate3d(1.2%, 1.1%, 0) scale(1.03); }
}

body.iwon-page * { box-sizing: border-box; }

body.iwon-page .iwon-wrap { padding: 0 var(--iwon-gutter) 90px; }

/* GeneratePress ships container/typography defaults that fight the mockup.
   Neutralise them inside iWON templates only. */
body.iwon-page .site-content,
body.iwon-page .content-area,
body.iwon-page .site-main { margin: 0; padding: 0; max-width: none; }

/* GeneratePress's Customizer-generated stylesheet sets a bare
   `h1,h2,h3,h4,h5,h6 { color: var(--contrast) }` rule, where --contrast
   resolves to #141414 — a near-black chosen for the legacy light-background
   site. Because that is a real declared rule (not mere inheritance), it
   silently wins over any iWON heading class that forgets to set its own
   `color` — which is exactly what happened to five of them. The five
   component rules (.iwon-headline, .iwon-page-title, .iwon-section-title,
   .iwon-card-title, .iwon-step-title) now each set color explicitly and no
   longer need this to win the cascade — but this stays as the general
   safety net, so a heading with no iWON class at all (verbatim legacy
   content on the Privacy Policy page, or any class added later) doesn't
   silently fall into the same trap. Ordinary specificity, no !important:
   `body.iwon-page h2` (0,1,2) already beats GP's bare `h2` (0,0,1). */
body.iwon-page h1,
body.iwon-page h2,
body.iwon-page h3,
body.iwon-page h4,
body.iwon-page h5,
body.iwon-page h6 {
  color: var(--iwon-text);
}

/* --------------------------------------------------------------------------
   Links

   THE BUG THIS FIXES, AND WHY THE COLOUR DECLARATION IS THE LOAD-BEARING PART
   --------------------------------------------------------------------------
   GeneratePress's Customizer stylesheet declares a bare `a { color:
   var(--contrast) }`, where --contrast is #141414 — a near-black picked for
   the legacy light site. This rule used to set `text-decoration` and nothing
   else, so for any anchor the design system did not style by name, GP's was
   the ONLY declaration of `color` and it won. Colour is inherited only in the
   absence of a matching declaration, and GP's counts as one.

   The result was 1.06:1 text on #0A0D10 — invisible. Measured on three
   surfaces before the fix: the mytinyteam.com link in the /products/ FAQ, the
   prev/next anchors under every blog post, and GP's "Skip to content" link,
   which unclips to 146x46px on focus and was therefore an invisible keyboard
   affordance on all 19 pages. This is the identical failure mode as the
   h1-h6 fix above; the cure is the same — declare the property.

   So the base below sets a colour for EVERY anchor on an iWON surface. It is
   deliberately a visible link blue rather than `inherit`: a component that
   wants something else already declares its own colour and out-ranks this at
   (0,2,1)+ against this rule's (0,1,2) — nav, logo, CTA, buttons, footer,
   breadcrumb, tags, pagination and card titles were each confirmed to do so
   by auditing every rendered anchor. Anything NEW therefore fails safe:
   readable, and obviously a link.
   -------------------------------------------------------------------------- */

body.iwon-page a {
  text-decoration: none;
  color: var(--iwon-blue-light);
}

/* Prose links get the underline as well.
 *
 * ONE rule for every reading surface, rather than a second treatment beside
 * the blog's: these declarations were `.iwon-article a` alone, and the
 * selector list is simply extended, so the article and the rest cannot drift
 * apart. Underline is confined to prose because in nav, cards and buttons a
 * colour change is the right affordance and an underline is noise — but in
 * running text colour alone is weak, and fails anyone who cannot separate
 * blue from grey.
 *
 * The two generic containers carry a :not() guard because both can hold a
 * button (the blog intro's CTA band does today) and a button must keep its
 * white-on-blue treatment. */
body.iwon-page .iwon-article a,
body.iwon-page .iwon-faq-a a,
body.iwon-page .iwon-faq-item > *:not(summary) a,
body.iwon-page .iwon-card-desc a,
body.iwon-page .iwon-section-intro a,
body.iwon-page .iwon-step-desc a,
body.iwon-page .iwon-page-sub a,
body.iwon-page .iwon-proof-text a,
body.iwon-page .iwon-empty-text a,
body.iwon-page .iwon-comment-body a,
body.iwon-page .iwon-section > p a:not(.iwon-btn-primary):not(.iwon-btn-ghost),
body.iwon-page .iwon-blog-intro a:not(.iwon-btn-primary):not(.iwon-btn-ghost) {
  color: var(--iwon-blue-light);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: rgba(76, 140, 245, 0.45);
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}

body.iwon-page .iwon-article a:hover,
body.iwon-page .iwon-faq-a a:hover,
body.iwon-page .iwon-faq-item > *:not(summary) a:hover,
body.iwon-page .iwon-card-desc a:hover,
body.iwon-page .iwon-section-intro a:hover,
body.iwon-page .iwon-step-desc a:hover,
body.iwon-page .iwon-page-sub a:hover,
body.iwon-page .iwon-proof-text a:hover,
body.iwon-page .iwon-empty-text a:hover,
body.iwon-page .iwon-comment-body a:hover,
body.iwon-page .iwon-section > p a:not(.iwon-btn-primary):not(.iwon-btn-ghost):hover,
body.iwon-page .iwon-blog-intro a:not(.iwon-btn-primary):not(.iwon-btn-ghost):hover {
  color: var(--iwon-blue-lighter);
  text-decoration-color: currentColor;
}

/* GP's skip link — the first thing a keyboard user reaches on every page.
   GP unclips it on focus but leaves it transparent-backed, so with the colour
   fix alone it would be blue text over whatever it happens to sit on. Give it
   a solid surface, and a z-index above the sticky nav (z-index: 50) so it is
   not painted behind the header it precedes. */
body.iwon-page .screen-reader-text:focus {
  background: var(--iwon-blue);
  color: #FFFFFF;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 14px;
  padding: 12px 20px;
  border-radius: var(--iwon-radius-sm);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
  text-decoration: none;
  z-index: 100;
}

body.iwon-page img,
body.iwon-page svg { max-width: 100%; height: auto; }

/* Page hero artwork.
 *
 * This is the first block in the content on 17 of the 19 pages, so it lands
 * directly under the page hero text and directly above the first
 * .iwon-section. The bottom margin is what keeps it off that section's
 * border-top — without it the artwork and the rule read as one crowded unit.
 *
 * Border and radius are the glass-panel treatment rather than anything new:
 * the artwork is drawn on the same #0A0D10 the page uses, so with no edge at
 * all it bleeds into the background and stops reading as a discrete image.
 */
body.iwon-page .iwon-hero-figure {
  margin: 4px 0 34px;
}

body.iwon-page .iwon-hero-figure img {
  display: block;
  width: 100%;
  border-radius: var(--iwon-radius);
  border: 1px solid var(--iwon-glass-border);
}

/* Visible focus — the mockups omit focus states entirely; adding them here
   rather than shipping a keyboard trap. */
body.iwon-page :focus-visible {
  outline: 2px solid var(--iwon-blue-light);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --------------------------------------------------------------------------
   Typography roles
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-eyebrow {
  font-family: var(--iwon-font-mono);
  font-size: 12px;
  letter-spacing: 3px;
  color: var(--iwon-amber);
  text-transform: uppercase;
  margin-bottom: 20px;
}

body.iwon-page .iwon-headline {
  font-family: var(--iwon-font-display);
  font-weight: 700;
  font-size: 46px;
  line-height: 1.14;
  letter-spacing: -0.5px;
  margin: 0;
  /* GeneratePress's Customizer CSS sets a bare `h1{color:var(--contrast)}`
     rule (--contrast: #141414, a near-black meant for the legacy light
     site). Explicit color here is required — without it there is nothing
     to out-rank that rule, since color is only inherited in the absence
     of any matching declaration, and GP's counts as one. */
  color: var(--iwon-text);
}

body.iwon-page .iwon-headline .iwon-accent {
  background: linear-gradient(90deg, var(--iwon-blue-light), var(--iwon-blue-lighter));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

body.iwon-page .iwon-sub {
  font-size: 16.5px;
  color: var(--iwon-text-muted);
  max-width: 520px;
  margin-top: 20px;
  line-height: 1.65;
}

body.iwon-page .iwon-section-label {
  font-family: var(--iwon-font-mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--iwon-text-faint);
  text-transform: uppercase;
  margin-bottom: 6px;
}

body.iwon-page .iwon-section-title {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 22px;
  margin: 0 0 28px;
  /* See .iwon-headline above — GP's bare h1-h6 selector wins without this. */
  color: var(--iwon-text);
}

body.iwon-page .iwon-divider {
  border-top: 1px solid var(--iwon-border-2);
  margin: 72px 0 40px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-btn-primary,
body.iwon-page .iwon-btn-ghost {
  display: inline-block;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 14px;
  padding: 13px 24px;
  border-radius: var(--iwon-radius-sm);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

body.iwon-page .iwon-btn-primary {
  background: var(--iwon-blue);
  color: #FFFFFF;
  border: none;
  box-shadow: 0 0 24px rgba(45, 108, 223, 0.35);
}

body.iwon-page .iwon-btn-primary:hover {
  background: var(--iwon-blue-light);
  box-shadow: 0 0 30px rgba(45, 108, 223, 0.5);
}

body.iwon-page .iwon-btn-ghost {
  background: rgba(255, 255, 255, 0.03);
  color: var(--iwon-text);
  border: 1px solid var(--iwon-border-3);
}

body.iwon-page .iwon-btn-ghost:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--iwon-blue-light);
}

body.iwon-page .iwon-cta-row {
  display: flex;
  gap: 14px;
  margin-top: 34px;
}

/* --------------------------------------------------------------------------
   Glass card — single component shared by the homepage solutions grid
   and the service-page feature grid (was .card / .feature-card in the mockups)
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-card {
  background: var(--iwon-glass-bg);
  -webkit-backdrop-filter: var(--iwon-glass-blur);
  backdrop-filter: var(--iwon-glass-blur);
  border: 1px solid var(--iwon-glass-border);
  border-radius: var(--iwon-radius);
  padding: 22px 20px;
  transition:
    border-color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

body.iwon-page .iwon-card:hover {
  border-color: rgba(76, 140, 245, 0.45);
  transform: translateY(-3px);
  box-shadow:
    0 6px 22px rgba(45, 108, 223, 0.10),
    0 0 0 1px rgba(76, 140, 245, 0.10);
}

/* A card that is actually a link gets a stronger tell than a static one, so
   "this is clickable" is legible before the cursor changes. */
body.iwon-page .iwon-card:has(.iwon-card-title a):hover {
  border-color: rgba(76, 140, 245, 0.62);
  box-shadow:
    0 8px 28px rgba(45, 108, 223, 0.16),
    0 0 0 1px rgba(76, 140, 245, 0.20);
}

/* Roomier padding when used as a service-page feature card */
body.iwon-page .iwon-card--feature { padding: 24px; }

body.iwon-page .iwon-card--featured {
  border: 1px solid rgba(76, 140, 245, 0.5);
  background: rgba(45, 108, 223, 0.06);
  box-shadow: 0 0 30px rgba(45, 108, 223, 0.12);
}

body.iwon-page .iwon-card-tag {
  font-family: var(--iwon-font-mono);
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--iwon-text-faint);
  text-transform: uppercase;
  margin-bottom: 12px;
}

body.iwon-page .iwon-card--featured .iwon-card-tag { color: var(--iwon-amber); }

body.iwon-page .iwon-card-title {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 15.5px;
  margin: 0 0 6px;
  /* See .iwon-headline above — GP's bare h1-h6 selector wins without this. */
  color: var(--iwon-text);
}

body.iwon-page .iwon-card-desc {
  font-size: 12.5px;
  color: var(--iwon-text-dimmer);
  line-height: 1.55;
}

/* --------------------------------------------------------------------------
   Clickable cards

   The approved mockups render solution cards as plain <div class="card">, so
   the built pages had no link to any of the eleven solution pages — six of
   them were reachable from nowhere on the site.

   The anchor is placed on the card TITLE rather than wrapped around the card,
   for two reasons: a core/group block cannot render as an <a>, and the link's
   accessible name should be the service name rather than the entire card's
   text read out as one label. The zero-size ::after then stretches that single
   anchor across the whole card, so the entire surface stays clickable. This is
   the standard "stretched link" pattern.

   Requires .iwon-card to be the positioned ancestor — hence position:relative
   below, which nothing else in the card relies on.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-card { position: relative; }

body.iwon-page .iwon-card-title a {
  color: inherit;
  text-decoration: none;
}

body.iwon-page .iwon-card-title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* Keyboard focus belongs on the whole card, not on the title text alone. */
body.iwon-page .iwon-card:has(.iwon-card-title a:focus-visible) {
  outline: 2px solid var(--iwon-blue-light);
  outline-offset: 2px;
}

body.iwon-page .iwon-card-title a:focus-visible { outline: none; }

/* The card already lifts and brightens on hover; make the pointer agree. */
body.iwon-page .iwon-card:has(.iwon-card-title a) { cursor: pointer; }

/* Feature-card variant runs slightly larger type (per service mockup) */
body.iwon-page .iwon-card--feature .iwon-card-title { margin-bottom: 8px; }
body.iwon-page .iwon-card--feature .iwon-card-desc {
  font-size: 13px;
  color: var(--iwon-text-dim);
  line-height: 1.6;
}

/* A card placed directly in a section (no grid around it — the /products/
   featured card) runs the full content width, where an uncapped description
   is a 200-character line. Cap it at a readable measure; cards inside grids
   never reach this width, so they are untouched. */
body.iwon-page .iwon-section > .iwon-card .iwon-card-desc { max-width: 760px; }

/* --------------------------------------------------------------------------
   Card icons

   Injected server-side by inc/card-icons.php, which prepends a single
   <span class="iwon-card-icon"> as the card's FIRST child and adds
   .iwon-card--has-icon to the card. Nothing else about the card's markup
   changes — the tag, title and description stay exactly where the editor put
   them.

   The approved layout (icon left, tag+title stacked to its right, description
   full-width below) is therefore produced entirely by grid PLACEMENT rather
   than by wrapping elements in new containers. That is the whole reason the
   injection can be a one-element insert: restructuring authored markup at
   render time is where this kind of filter usually breaks something.

   Only the two rows above the description are beside the icon, so the icon
   spans rows 1-2 when a tag is present and row 1 alone when it is not.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-card--has-icon {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr);
  column-gap: 14px;
  row-gap: 0;
  align-items: start;
}

body.iwon-page .iwon-card-icon {
  grid-column: 1;
  grid-row: 1;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: rgba(76, 140, 245, 0.1);
  border: 1px solid rgba(76, 140, 245, 0.25);
  color: var(--iwon-blue-light);
  flex-shrink: 0;
  transition: background 0.18s ease, border-color 0.18s ease;
}

/* With a tag above the title there are two text rows to sit beside. */
body.iwon-page .iwon-card--has-icon:has(.iwon-card-tag) .iwon-card-icon {
  grid-row: 1 / span 2;
}

body.iwon-page .iwon-card--has-icon .iwon-card-tag,
body.iwon-page .iwon-card--has-icon .iwon-card-title {
  grid-column: 2;
  margin-bottom: 0;
}

/* The tag sits tight under nothing and directly above the title here, so its
   default 12px gap (which existed to separate it from the title in the old
   stacked layout) becomes too much inside a 38px-tall header row. */
body.iwon-page .iwon-card--has-icon .iwon-card-tag { margin-bottom: 3px; }

/* No tag: one text row, so centre it against the tile instead of leaving a
   single line hanging at the top of a 38px box. Flex rather than align-self so
   a title that wraps to two lines still centres as a block. */
body.iwon-page .iwon-card--has-icon:not(:has(.iwon-card-tag)) .iwon-card-title {
  display: flex;
  align-items: center;
  min-height: 38px;
}

body.iwon-page .iwon-card--has-icon .iwon-card-desc {
  grid-column: 1 / -1;
  margin-top: 14px;
}

/* Featured/flagship cards take the amber variant. Scoped to .iwon-card--featured
   — the single card the design system already treats as featured — rather than
   to everything tagged "Flagship", which is four more cards in the same grid
   and would leave the actual featured card with nothing to distinguish it. */
body.iwon-page .iwon-card--featured .iwon-card-icon {
  background: rgba(242, 169, 59, 0.08);
  border-color: rgba(242, 169, 59, 0.25);
  color: var(--iwon-amber);
}

/* The tile brightens with the card it belongs to. */
body.iwon-page .iwon-card--has-icon:hover .iwon-card-icon {
  background: rgba(76, 140, 245, 0.16);
  border-color: rgba(76, 140, 245, 0.4);
}

body.iwon-page .iwon-card--featured:hover .iwon-card-icon {
  background: rgba(242, 169, 59, 0.14);
  border-color: rgba(242, 169, 59, 0.4);
}

body.iwon-page .iwon-card-icon svg { display: block; }

/* Grids */
body.iwon-page .iwon-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}

body.iwon-page .iwon-grid--2 {
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-hero {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 20px;
  align-items: center;
  min-height: 460px;
  padding-top: 56px;
}

body.iwon-page .iwon-canvas-wrap {
  width: 100%;
  height: 420px;
  position: relative;
}

body.iwon-page .iwon-canvas-wrap canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
}

/* --------------------------------------------------------------------------
   Proof strip
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-proof {
  margin-top: 56px;
  padding-top: 32px;
  border-top: 1px solid var(--iwon-border-2);
  display: flex;
  align-items: center;
  gap: 16px;
}

body.iwon-page .iwon-proof-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--iwon-amber);
  flex-shrink: 0;
}

body.iwon-page .iwon-proof-text {
  font-size: 13.5px;
  color: var(--iwon-text-proof);
  line-height: 1.6;
  max-width: 620px;
}

/* --------------------------------------------------------------------------
   Interior page furniture (service template)
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-breadcrumb {
  font-family: var(--iwon-font-mono);
  font-size: 11.5px;
  color: var(--iwon-text-faint);
  padding-top: 30px;
}

body.iwon-page .iwon-breadcrumb a { color: var(--iwon-text-dimmer); }
body.iwon-page .iwon-breadcrumb a:hover { color: var(--iwon-text-nav); }
body.iwon-page .iwon-breadcrumb .iwon-current { color: var(--iwon-amber); }

body.iwon-page .iwon-page-hero {
  padding: 24px 0 50px;
  max-width: 720px;
}

body.iwon-page .iwon-tag {
  display: inline-block;
  font-family: var(--iwon-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--iwon-amber);
  background: rgba(242, 169, 59, 0.08);
  border: 1px solid rgba(242, 169, 59, 0.3);
  padding: 5px 10px;
  border-radius: 3px;
  margin-bottom: 18px;
}

body.iwon-page .iwon-page-title {
  font-family: var(--iwon-font-display);
  font-weight: 700;
  font-size: 38px;
  line-height: 1.15;
  margin: 0 0 18px;
  /* See .iwon-headline above — GP's bare h1-h6 selector wins without this. */
  color: var(--iwon-text);
}

body.iwon-page .iwon-page-sub {
  font-size: 16px;
  color: var(--iwon-text-muted);
  line-height: 1.65;
}

/* --------------------------------------------------------------------------
   404 — utility page

   Reuses the interior page hero wholesale; the only new component is the
   search field, which needs styling because GeneratePress's is built for a
   light background and reads as a white box on the dark theme.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-404 { padding: 60px 0 110px; }

body.iwon-page .iwon-search {
  display: flex;
  gap: 10px;
  margin-top: 30px;
  max-width: 470px;
}

body.iwon-page .iwon-search input[type="search"] {
  flex: 1;
  min-width: 0;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  color: var(--iwon-text);
  font-family: var(--iwon-font-body);
  font-size: 14px;
  padding: 12px 14px;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

body.iwon-page .iwon-search input[type="search"]::placeholder {
  color: var(--iwon-text-faint);
}

body.iwon-page .iwon-search input[type="search"]:focus {
  outline: none;
  border-color: var(--iwon-blue-light);
  box-shadow: 0 0 0 3px rgba(76, 140, 245, 0.15);
}

body.iwon-page .iwon-search button { border: none; }

@media (max-width: 520px) {
  body.iwon-page .iwon-search {
    flex-direction: column;
    max-width: none;
  }
}

/* --------------------------------------------------------------------------
   Contact form (Contact Form 7, /contact/)

   CF7's markup is plain spans and inputs; these rules dress it in the same
   field language as the 404 search box above (same surface, border, focus
   ring) so the two forms on the site read as one system. Field labels take
   the mono section-label voice. Everything is scoped under body.iwon-page
   .wpcf7 — legacy pages keep whatever their theme did.

   State colours: the palette has no red or green, so these are chosen to sit
   in it rather than pop against it — desaturated red (#E5484D family) for
   failure, muted green for success, and the existing amber for "check your
   fields", which is a notice rather than a failure. Specificity beats CF7's
   own stylesheet (its selectors carry no body class).
   -------------------------------------------------------------------------- */

body.iwon-page .wpcf7 {
  max-width: 640px;
  margin-top: 26px;
}

body.iwon-page .iwon-field { margin-bottom: 18px; }

body.iwon-page .iwon-field label {
  display: block;
  font-family: var(--iwon-font-mono);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--iwon-text-dim);
  margin-bottom: 8px;
}

body.iwon-page .wpcf7 .wpcf7-form-control-wrap { display: block; }

body.iwon-page .wpcf7 input[type="text"],
body.iwon-page .wpcf7 input[type="email"],
body.iwon-page .wpcf7 input[type="tel"],
body.iwon-page .wpcf7 input[type="url"],
body.iwon-page .wpcf7 textarea {
  display: block;
  width: 100%;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  color: var(--iwon-text);
  font-family: var(--iwon-font-body);
  font-size: 14px;
  padding: 12px 14px;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

body.iwon-page .wpcf7 textarea {
  min-height: 150px;
  resize: vertical;
}

/* Select ("Which service are you interested in?"): same box as the inputs,
   with an inline SVG caret (data URI, no external asset). */
body.iwon-page .wpcf7 select {
  display: block;
  width: 100%;
  background: rgba(255, 255, 255, 0.03) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%239AA3AD' stroke-width='1.6'/%3E%3C/svg%3E") no-repeat right 14px center;
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  color: var(--iwon-text);
  font-family: var(--iwon-font-body);
  font-size: 14px;
  padding: 12px 40px 12px 14px;
  -webkit-appearance: none;
  appearance: none;
}
body.iwon-page .wpcf7 select option { background: #0A0D10; color: var(--iwon-text); }
body.iwon-page .wpcf7 select:focus {
  outline: none;
  border-color: var(--iwon-blue-light);
  box-shadow: 0 0 0 3px rgba(76, 140, 245, 0.15);
}

body.iwon-page .wpcf7 input:focus,
body.iwon-page .wpcf7 textarea:focus {
  outline: none;
  border-color: var(--iwon-blue-light);
  box-shadow: 0 0 0 3px rgba(76, 140, 245, 0.15);
}

/* Submit — same recipe as .iwon-btn-primary (that class can't be put on the
   control: CF7 owns the [submit] tag's markup). */
body.iwon-page .wpcf7 input[type="submit"] {
  display: inline-block;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 14px;
  padding: 13px 24px;
  border: none;
  border-radius: var(--iwon-radius-sm);
  background: var(--iwon-blue);
  color: #FFFFFF;
  cursor: pointer;
  box-shadow: 0 0 24px rgba(45, 108, 223, 0.35);
  transition: background 0.15s ease, box-shadow 0.15s ease;
  margin-top: 4px;
}

body.iwon-page .wpcf7 input[type="submit"]:hover {
  background: var(--iwon-blue-light);
  box-shadow: 0 0 30px rgba(45, 108, 223, 0.5);
}

body.iwon-page .wpcf7 input[type="submit"]:disabled {
  opacity: 0.6;
  cursor: default;
}

/* CF7's inline spinner sits beside the submit; its default disc is a dark
   grey that vanishes on this background. */
body.iwon-page .wpcf7 .wpcf7-spinner {
  background-color: var(--iwon-blue-light);
}

/* Per-field validation message, injected under the control. */
body.iwon-page .wpcf7 .wpcf7-not-valid-tip {
  display: block;
  font-size: 12.5px;
  color: #F0757B;
  margin-top: 8px;
}

/* Element-qualified to outrank the base input/textarea rules above (they
   carry an attribute selector; class alone ties below them). */
body.iwon-page .wpcf7 input.wpcf7-not-valid,
body.iwon-page .wpcf7 textarea.wpcf7-not-valid {
  border-color: rgba(229, 72, 77, 0.55);
}

/* Response banner. Base look first, then the three outcome families —
   CF7 stamps the state class on the <form> element. */
body.iwon-page .wpcf7 .wpcf7-response-output {
  margin: 22px 0 0;
  padding: 13px 16px;
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--iwon-text-muted);
}

body.iwon-page .wpcf7 form.sent .wpcf7-response-output {
  border-color: rgba(80, 178, 101, 0.45);
  background: rgba(80, 178, 101, 0.08);
  color: #8FD69B;
}

body.iwon-page .wpcf7 form.invalid .wpcf7-response-output,
body.iwon-page .wpcf7 form.unaccepted .wpcf7-response-output,
body.iwon-page .wpcf7 form.payment-required .wpcf7-response-output {
  border-color: rgba(242, 169, 59, 0.45);
  background: rgba(242, 169, 59, 0.07);
  color: #F2C57B;
}

body.iwon-page .wpcf7 form.failed .wpcf7-response-output,
body.iwon-page .wpcf7 form.spam .wpcf7-response-output {
  border-color: rgba(229, 72, 77, 0.45);
  background: rgba(229, 72, 77, 0.08);
  color: #F0989C;
}

/* reCAPTCHA attribution under the form. Required wording: the legacy
   Customizer CSS hides the .grecaptcha-badge site-wide, and Google's terms
   allow a hidden badge only when this line appears in the user flow. */
body.iwon-page .iwon-form-note {
  max-width: 640px;
  margin-top: 14px;
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--iwon-text-faint);
}

body.iwon-page .iwon-form-note a {
  color: var(--iwon-text-dimmer);
  text-decoration: underline;
  text-underline-offset: 2px;
}

body.iwon-page .iwon-form-note a:hover { color: var(--iwon-text-nav); }

body.iwon-page .iwon-section {
  padding: 46px 0;
  border-top: 1px solid var(--iwon-border);
}

body.iwon-page .iwon-section .iwon-section-label { margin-bottom: 10px; }

body.iwon-page .iwon-section .iwon-section-title {
  font-size: 24px;
  max-width: 640px;
  margin-bottom: 18px;
}

/* Optional lead paragraph beneath a section title. Added in template v2 —
   gives each service page a natural place for context, and is part of how
   pages clear the ~480-word floor. */
body.iwon-page .iwon-section-intro {
  font-size: 14.5px;
  color: var(--iwon-text-dim);
  line-height: 1.7;
  max-width: 660px;
  margin-bottom: 30px;
}

/* --------------------------------------------------------------------------
   How It Works — process flow

   Four steps drawn as a connected sequence rather than four glass cards: a
   42px circular node per step (the step number in mono amber over a
   blue-tinted disc), title and description in open space below, and a thin
   gradient line running from each node toward the next.

   THE MARKUP IS UNCHANGED. The authored "Step 01" paragraph IS the node: its
   text is hidden at font-size 0 (still present for screen readers) and the
   two digits are redrawn by the `iwon-step` counter the grid already resets.
   That is why this restyle needed no render filter and no DB edit — and why
   the number can never disagree with the step's actual position.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: 20px;
  counter-reset: iwon-step;
}

body.iwon-page .iwon-step {
  position: relative;
  counter-increment: iwon-step;
}

/* The node. Painted directly on the page surface — the glass panel is gone,
   which is what makes these read as one diagram instead of four boxes. */
body.iwon-page .iwon-step-num {
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(76, 140, 245, 0.08);
  border: 1px solid rgba(76, 140, 245, 0.4);
  font-family: var(--iwon-font-mono);
  font-size: 0; /* hides the authored "Step 01" without removing it from AT */
  color: var(--iwon-amber);
  margin: 0 0 18px;
  position: relative;
  z-index: 1; /* above the connector, so the line can never strike through */
}

body.iwon-page .iwon-step-num::before {
  content: counter(iwon-step, decimal-leading-zero);
  /* Alt-text form second: browsers that understand it hide the digits from
     screen readers (the hidden "Step 01" text already announces the number);
     older engines ignore this line and keep the plain declaration above. */
  content: counter(iwon-step, decimal-leading-zero) / '';
  font-size: 13.5px;
  letter-spacing: 0.5px;
  line-height: 1;
}

body.iwon-page .iwon-step-title {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 15.5px;
  margin: 0 0 8px;
  /* See .iwon-headline above — GP's bare h1-h6 selector wins without this. */
  color: var(--iwon-text);
}

body.iwon-page .iwon-step-desc {
  font-size: 13px;
  color: var(--iwon-text-dim);
  line-height: 1.6;
  margin: 0;
}

/* Connector: node N reaches toward node N+1. Anchored to the node band
   (top 21px = the disc's centre), so text length below can never bend it. */
body.iwon-page .iwon-step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 21px;
  left: 54px;       /* 42px disc + 12px clearance */
  right: -6px;      /* stops 8px short of the next disc across the 14px gap */
  height: 1px;
  background: linear-gradient(90deg, rgba(76, 140, 245, 0.5), rgba(76, 140, 245, 0.15));
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   FAQ accordion (NEW, extends the approved template)
   Built on native <details>/<summary>: expand/collapse works with zero JS,
   is keyboard accessible, and is exposed correctly to screen readers.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-faq { max-width: 820px; }

body.iwon-page .iwon-faq-item {
  background: var(--iwon-glass-bg);
  -webkit-backdrop-filter: var(--iwon-glass-blur);
  backdrop-filter: var(--iwon-glass-blur);
  border: 1px solid var(--iwon-glass-border);
  border-radius: var(--iwon-radius);
  margin-bottom: 10px;
  overflow: hidden;
  transition: border-color 0.18s ease;
}

body.iwon-page .iwon-faq-item[open] { border-color: rgba(76, 140, 245, 0.35); }

/* Two selectors throughout: `.iwon-faq-q` for hand-authored markup, and the
   bare `summary` for WordPress's core/details block, which renders its own
   <summary> and gives us no hook to add a class to it. */
body.iwon-page .iwon-faq-q,
body.iwon-page .iwon-faq-item > summary {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--iwon-text);
  padding: 18px 46px 18px 20px;
  cursor: pointer;
  position: relative;
  list-style: none;
}

/* Kill the native disclosure triangle in both engines */
body.iwon-page .iwon-faq-q::-webkit-details-marker,
body.iwon-page .iwon-faq-item > summary::-webkit-details-marker { display: none; }
body.iwon-page .iwon-faq-q::marker,
body.iwon-page .iwon-faq-item > summary::marker { content: ''; }

/* Custom +/- indicator */
body.iwon-page .iwon-faq-q::after,
body.iwon-page .iwon-faq-item > summary::after {
  content: '';
  position: absolute;
  right: 20px;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-top: -5px;
  background:
    linear-gradient(var(--iwon-text-faint), var(--iwon-text-faint)) center / 10px 1.5px no-repeat,
    linear-gradient(var(--iwon-text-faint), var(--iwon-text-faint)) center / 1.5px 10px no-repeat;
  transition: transform 0.2s ease, background 0.2s ease;
}

body.iwon-page .iwon-faq-item[open] .iwon-faq-q::after,
body.iwon-page .iwon-faq-item[open] > summary::after {
  transform: rotate(90deg);
  background:
    linear-gradient(var(--iwon-amber), var(--iwon-amber)) center / 10px 1.5px no-repeat;
}

/* Answer body — `.iwon-faq-a` when hand-authored, or any non-summary child
   when produced by core/details. */
body.iwon-page .iwon-faq-a,
body.iwon-page .iwon-faq-item > *:not(summary) {
  padding: 0 20px 20px;
  font-size: 13.5px;
  color: var(--iwon-text-dim);
  line-height: 1.7;
  max-width: 720px;
  margin: 0;
}

/* --------------------------------------------------------------------------
   CTA band
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-cta-band {
  margin-top: 30px;
  padding: 40px;
  border-radius: 12px;
  background: rgba(45, 108, 223, 0.06);
  border: 1px solid rgba(76, 140, 245, 0.3);
  box-shadow: 0 0 40px rgba(45, 108, 223, 0.1);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

body.iwon-page .iwon-cta-band-title {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 19px;
  max-width: 380px;
}

body.iwon-page .iwon-cta-band .iwon-btn-primary { white-space: nowrap; }

/* Two buttons in a band (per-page optional second CTA). */
body.iwon-page .iwon-cta-band-btns {
  display: flex;
  flex: 0 1 auto;
  flex-wrap: nowrap;
  gap: 14px;
}
@media (max-width: 640px) {
  body.iwon-page .iwon-cta-band-btns { flex-wrap: wrap; }
}
body.iwon-page .iwon-cta-band .iwon-btn-ghost { white-space: nowrap; }

/* ==========================================================================
   BLOG — index, archives, search results, single post

   Nothing here introduces a second visual language. The post card IS
   .iwon-card, which means it inherits the glass panel, the hover lift, the
   stretched link and — because iwon-ui.js already watches `.iwon-card` — the
   scroll reveal, with no new JS and no new selector added to the observer.
   The rules below only supply what a card of prose needs that a card of two
   lines does not.
   ========================================================================== */

body.iwon-page .iwon-post-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

/* Three across on desktop, two in the band below it.
 *
 * At the 1440px reference width a column is ~400px. Measured there: titles
 * wrap to two lines, the 26-word excerpt runs to three, and the grid's default
 * stretch keeps every card in a row the same height, so the ragged excerpt
 * lengths do not show. The thumbnail also reads BETTER than it did at two
 * columns — 150px tall against ~400px is 2.7:1, where the old 612px column
 * made it a 4:1 letterbox — which is why its height is unchanged.
 *
 * The 1100px floor is what keeps that true. Three columns at 900px would be
 * ~250px each, which is narrower than the thumbnail is tall and turns every
 * title into four lines. Below 1100 the grid drops to two, and the existing
 * 860px rule still takes it to one — so nothing at tablet or phone width
 * changes from what shipped. */
@media (max-width: 1100px) {
  body.iwon-page .iwon-post-grid { grid-template-columns: repeat(2, 1fr); }
}

body.iwon-page .iwon-card--post { padding: 24px 22px; }

body.iwon-page .iwon-card--post .iwon-card-title {
  font-size: 17px;
  line-height: 1.35;
  margin-bottom: 10px;
}

body.iwon-page .iwon-card--post .iwon-card-desc {
  font-size: 13px;
  color: var(--iwon-text-dim);
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   Post card thumbnails

   Full-bleed to the card's inner edge via negative margins that exactly cancel
   .iwon-card--post's 24px/22px padding, so the tile meets the card border
   without the card itself needing overflow:hidden — which would have clipped
   the focus outline the card draws for keyboard users.

   The radius is `--iwon-radius` minus the 1px border, so the tile's corners sit
   concentrically inside the card's rather than half a pixel proud of them.

   FIXED HEIGHT, NOT ASPECT RATIO: every card in a row must have its title on
   the same baseline, and the 155 featured images range from 150x150 to
   1920x985. A fixed 150px box with object-fit: cover is what makes the grid
   line up, and it also means the image can never move the layout as it loads.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-card-thumb {
  position: relative;
  height: 150px;
  margin: -24px -22px 18px;
  border-radius: calc(var(--iwon-radius) - 1px) calc(var(--iwon-radius) - 1px) 0 0;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.02);
}

body.iwon-page .iwon-card-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /*
   * NO background-color here, deliberately. WP Rocket's LazyLoad swaps `src`
   * for a transparent inline SVG placeholder, so any light backing would paint
   * as a bright rectangle on the dark grid until the real image arrived — the
   * exact regression already fixed once for article images. The card's own dark
   * surface is what shows through while loading.
   */
}

/* Fade the foot of the image into the card so the title below always sits on
   the card surface rather than on whatever the photo happens to end with. */
body.iwon-page .iwon-card-thumb--image::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(10, 13, 16, 0) 40%, rgba(10, 13, 16, 0.85));
}

/* Generated tile for the ~87 posts with no featured image. Two token-coloured
   variants alternating by post ID, over a fine diagonal rule pattern that gives
   the surface some texture without becoming a subject in its own right. */
body.iwon-page .iwon-card-thumb--gen {
  background-image:
    repeating-linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.045) 0 1px,
      transparent 1px 9px
    ),
    linear-gradient(140deg, rgba(45, 108, 223, 0.32), rgba(45, 108, 223, 0.05));
}

body.iwon-page .iwon-card-thumb--gen.iwon-card-thumb--alt {
  background-image:
    repeating-linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.045) 0 1px,
      transparent 1px 9px
    ),
    /* Slightly hotter than the blue variant's alpha. Amber loses its hue far
       faster than blue does when composited onto #0A0D10 — at the blue's 0.32
       it resolves to rgb(70,54,27), which reads as brown rather than as the
       amber token. This is the alpha at which it still reads warm. */
    linear-gradient(140deg, rgba(242, 169, 59, 0.34), rgba(242, 169, 59, 0.05));
}

body.iwon-page .iwon-card-thumb-chip {
  position: absolute;
  left: 16px;
  bottom: 14px;
  font-family: var(--iwon-font-mono);
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--iwon-text-nav);
  background: rgba(10, 13, 16, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  padding: 4px 9px;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

body.iwon-page .iwon-card-thumb--alt .iwon-card-thumb-chip { color: var(--iwon-amber); }

/* The card lifts on hover; give the image the smallest matching response. */
body.iwon-page .iwon-card--post .iwon-card-thumb img {
  transition: transform 0.35s ease;
}

body.iwon-page .iwon-card--post:hover .iwon-card-thumb img {
  transform: scale(1.03);
}

@media (prefers-reduced-motion: reduce) {
  body.iwon-page .iwon-card--post:hover .iwon-card-thumb img { transform: none; }
}

/* The posts page's own authored content, rendered above the listing by
   home.php. The exclusion is written against .iwon-section-intro rather than
   `p:not([class])`, because WordPress puts `wp-block-paragraph` on every
   paragraph it renders — there are no unclassed paragraphs in block content. */
body.iwon-page .iwon-blog-intro > p:not(.iwon-section-intro) {
  font-size: 15px;
  color: var(--iwon-text-dim);
  line-height: 1.7;
  max-width: 660px;
}

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 34px;
}

body.iwon-page .iwon-pagination .page-numbers {
  display: inline-block;
  font-family: var(--iwon-font-mono);
  font-size: 12px;
  color: var(--iwon-text-muted);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  padding: 9px 13px;
  min-width: 38px;
  text-align: center;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

body.iwon-page .iwon-pagination a.page-numbers:hover {
  color: var(--iwon-text);
  border-color: var(--iwon-blue-light);
  background: rgba(255, 255, 255, 0.06);
}

body.iwon-page .iwon-pagination .page-numbers.current {
  background: var(--iwon-blue);
  border-color: var(--iwon-blue);
  color: #FFFFFF;
  box-shadow: 0 0 18px rgba(45, 108, 223, 0.3);
}

body.iwon-page .iwon-pagination .page-numbers.dots {
  background: none;
  border-color: transparent;
  color: var(--iwon-text-faint);
  min-width: 0;
  padding-left: 2px;
  padding-right: 2px;
}

/* --------------------------------------------------------------------------
   Empty state (no results)
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-empty { padding-bottom: 10px; }

body.iwon-page .iwon-empty-text {
  font-size: 15px;
  color: var(--iwon-text-muted);
  line-height: 1.7;
  max-width: 560px;
  margin: 0 0 22px;
}

/* --------------------------------------------------------------------------
   Single post — header
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-post-hero {
  max-width: var(--iwon-read-width);
  padding-bottom: 26px;
}

body.iwon-page .iwon-post-hero .iwon-page-title { font-size: 34px; }

/* .iwon-tag is a <div> everywhere else; on a post it is the link to the
   category archive, so it needs a hover tell. */
body.iwon-page a.iwon-tag {
  transition: background 0.15s ease, border-color 0.15s ease;
}

body.iwon-page a.iwon-tag:hover {
  background: rgba(242, 169, 59, 0.16);
  border-color: rgba(242, 169, 59, 0.55);
}

body.iwon-page .iwon-post-meta {
  font-family: var(--iwon-font-mono);
  font-size: 11.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--iwon-text-faint);
}

body.iwon-page .iwon-post-thumb {
  margin: 0 0 34px;
  max-width: var(--iwon-read-width);
}

/* `max-width` and not `width`: featured images on this site range from
   256x256 to 1920px, and stretching every one of them to the 740px measure
   upscaled the small ones — the /usdt-card-comparison/ hero is a 500px file
   and was being drawn at 740px, visibly soft. Small images now sit at their
   own size. */
body.iwon-page .iwon-post-thumb img {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--iwon-radius);
  border: 1px solid var(--iwon-glass-border);
  background-color: var(--iwon-img-backing);
}

/* ==========================================================================
   Single post — the article body

   This is the only part of the system that styles markup it did not author.
   The 156 posts are 131 block-editor and 25 classic-editor documents written
   for a white page between 2016 and 2025. Audited before writing any of this:
   no [vc_*] shortcodes, no inline style attributes, no bgcolor, no <font>, no
   hardcoded colours of any kind. So there is nothing to override — only
   defaults to supply — and not one rule below needs !important.
   ========================================================================== */

body.iwon-page .iwon-article {
  max-width: var(--iwon-read-width);
  font-size: 17px;
  line-height: 1.75;
  color: var(--iwon-text-read);
}

/* Legacy content uses left/right floats for a handful of images. */
body.iwon-page .iwon-article::after {
  content: '';
  display: table;
  clear: both;
}

body.iwon-page .iwon-article p { margin: 0 0 1.35em; }

body.iwon-page .iwon-article > *:first-child { margin-top: 0; }
body.iwon-page .iwon-article > *:last-child { margin-bottom: 0; }

body.iwon-page .iwon-article h1,
body.iwon-page .iwon-article h2,
body.iwon-page .iwon-article h3,
body.iwon-page .iwon-article h4,
body.iwon-page .iwon-article h5,
body.iwon-page .iwon-article h6 {
  font-family: var(--iwon-font-display);
  font-weight: 600;
  color: var(--iwon-text);
  line-height: 1.3;
  margin: 1.9em 0 0.55em;
}

/*
 * h1 is styled identically to h2 on purpose.
 *
 * 66 posts open a SECTION with an <h1> — "AI in Search Engine Optimization",
 * "From Chatbots to Voice Assistants" — an old SEO habit, and the post title
 * is a separate <h1> in the header above. Left at a title's size those render
 * as a second, larger headline part-way down the page, which reads as the
 * article restarting. Sizing it as the h2 it actually is fixes the appearance
 * without editing 66 posts' stored content, which is the constraint here.
 * (The duplicate-h1 semantics remain; that is a content fix, not a CSS one.)
 */
body.iwon-page .iwon-article h1,
body.iwon-page .iwon-article h2 { font-size: 24px; }

body.iwon-page .iwon-article h3 { font-size: 19px; }
body.iwon-page .iwon-article h4 { font-size: 16.5px; }
body.iwon-page .iwon-article h5,
body.iwon-page .iwon-article h6 { font-size: 15px; }

/* Links: see "Content links" near the top of this file. `.iwon-article a` was
   the original home of that treatment; it now shares one rule with every other
   reading surface so the blog and the pages cannot drift apart. */

body.iwon-page .iwon-article ul,
body.iwon-page .iwon-article ol {
  margin: 0 0 1.35em;
  padding-left: 1.4em;
}

body.iwon-page .iwon-article li { margin-bottom: 0.5em; }
body.iwon-page .iwon-article li::marker { color: var(--iwon-blue-light); }

body.iwon-page .iwon-article li > ul,
body.iwon-page .iwon-article li > ol {
  margin-top: 0.5em;
  margin-bottom: 0;
}

body.iwon-page .iwon-article blockquote {
  margin: 1.8em 0;
  padding: 18px 22px;
  border-left: 2px solid var(--iwon-blue-light);
  border-radius: 0 var(--iwon-radius) var(--iwon-radius) 0;
  background: var(--iwon-glass-bg);
  color: var(--iwon-text-nav);
  font-size: 16.5px;
}

body.iwon-page .iwon-article blockquote p:last-child { margin-bottom: 0; }

body.iwon-page .iwon-article blockquote cite,
body.iwon-page .iwon-article blockquote .wp-block-quote__citation {
  display: block;
  margin-top: 10px;
  font-family: var(--iwon-font-mono);
  font-style: normal;
  font-size: 12px;
  color: var(--iwon-text-faint);
}

/* --------------------------------------------------------------------------
   Tables

   Five posts carry comparison tables, the widest at seven columns. Core's
   `has-fixed-layout` divides 740px equally between them, which puts "The card
   program is already closed" into a 105px column. Natural widths plus a
   scroll container on the figure keeps them legible instead.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-article .wp-block-table {
  margin: 1.8em 0;
  overflow-x: auto;
}

body.iwon-page .iwon-article table {
  border-collapse: collapse;
  min-width: 100%;
  width: max-content;
  max-width: none;
  font-size: 13.5px;
  line-height: 1.55;
  background: var(--iwon-glass-bg);
  border: 1px solid var(--iwon-glass-border);
  border-radius: var(--iwon-radius);
  overflow: hidden;
}

body.iwon-page .iwon-article table.has-fixed-layout { table-layout: auto; }

body.iwon-page .iwon-article th,
body.iwon-page .iwon-article td {
  padding: 11px 15px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--iwon-border-2);
}

body.iwon-page .iwon-article thead th {
  font-family: var(--iwon-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--iwon-text-faint);
  background: rgba(255, 255, 255, 0.03);
  border-bottom-color: var(--iwon-border-3);
  white-space: nowrap;
}

body.iwon-page .iwon-article td { color: var(--iwon-text-read); }
body.iwon-page .iwon-article tbody tr:last-child td { border-bottom: none; }

/* Separators. Core gives .has-alpha-channel-opacity `opacity: .4` over
   currentColor, which on a dark page draws a faint smear of body-text grey
   rather than the system's own divider. 79 of these across the posts. */
body.iwon-page .iwon-article hr,
body.iwon-page .iwon-article .wp-block-separator {
  height: 0;
  border: none;
  border-top: 1px solid var(--iwon-border-2);
  margin: 2.2em 0;
  opacity: 1;
}

/* --------------------------------------------------------------------------
   Images

   THE PROBLEM, MEASURED: 229 images across the posts, 74 of them in
   alpha-capable formats. Compositing every one of those onto #0A0D10 and
   looking at the result, roughly a third are diagrams exported with a
   transparent background and dark labels — the pyramid chart's tier names, the
   wheel labels in blog-brandreputation5.png, the "Business Plan & Strategy"
   text at the centre of blog-Ecommerce4.png. On white they were fine. On the
   dark page that text is drawn in near-black on near-black and is simply gone.

   THE FIX, AND WHY IT IS SAFE TO APPLY TO EVERY IMAGE: a background colour
   with NO padding. An opaque image — every JPEG, and the many PNGs that are
   screenshots with their own white background — covers its own box completely,
   so the colour behind it is never sampled and not one pixel changes. Only
   genuinely transparent regions reveal it. The rule is therefore self-
   targeting: it does nothing at all except in exactly the case that is broken.

   Padding would break that property (it would draw a light frame around every
   photo), which is why there is none. Nothing here filters or inverts the
   images.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-article img {
  display: block;
  height: auto;
  border-radius: var(--iwon-radius-sm);
  background-color: var(--iwon-img-backing);
}

/*
 * ...but not while the image is still lazy-loading.
 *
 * WP Rocket's LazyLoad swaps `src` for a TRANSPARENT inline SVG of the right
 * dimensions and moves the real URL to `data-lazy-src`. A transparent
 * placeholder over a light backing is a solid light rectangle — so every
 * not-yet-loaded image painted as a bright block on the dark page, and
 * scrolling a 30-image post set off a run of them. Posts are not covered by
 * the per-page-template LazyLoad exclusion (that keys on `_wp_page_template`),
 * and they should not be: lazy loading is worth having on articles this long.
 *
 * Keyed on WP Rocket's own attribute and its configured `class_loaded` value,
 * so the backing appears at the moment there is a real image to sit behind.
 * If LazyLoad is ever switched off the attribute never exists, this rule never
 * matches, and the backing simply applies from the start — the safe default.
 */
body.iwon-page .iwon-article img[data-lazy-src]:not(.lazyloaded),
body.iwon-page .iwon-post-thumb img[data-lazy-src]:not(.lazyloaded) {
  background-color: transparent;
}

body.iwon-page .iwon-article figure { margin: 1.9em 0; }

body.iwon-page .iwon-article figcaption,
body.iwon-page .iwon-article .wp-element-caption,
body.iwon-page .iwon-article .wp-caption-text {
  margin-top: 10px;
  font-family: var(--iwon-font-body);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--iwon-text-faint);
  text-align: center;
}

/* Classic-editor alignment classes — 25 posts predate the block editor and
   use these directly on the <img>, with no figure around them. */
body.iwon-page .iwon-article .aligncenter {
  margin-left: auto;
  margin-right: auto;
}

body.iwon-page .iwon-article .alignleft {
  float: left;
  margin: 0.3em 1.4em 1em 0;
}

body.iwon-page .iwon-article .alignright {
  float: right;
  margin: 0.3em 0 1em 1.4em;
}

body.iwon-page .iwon-article .alignnone {
  margin-left: 0;
  margin-right: 0;
}

/* Two posts use core buttons. Match the system's primary button rather than
   letting core paint its default. */
body.iwon-page .iwon-article .wp-block-button__link {
  display: inline-block;
  background: var(--iwon-blue);
  color: #FFFFFF;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 14px;
  padding: 13px 24px;
  border-radius: var(--iwon-radius-sm);
  text-decoration: none;
  box-shadow: 0 0 24px rgba(45, 108, 223, 0.35);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

body.iwon-page .iwon-article .wp-block-button__link:hover {
  background: var(--iwon-blue-light);
  color: #FFFFFF;
  box-shadow: 0 0 30px rgba(45, 108, 223, 0.5);
}

/* --------------------------------------------------------------------------
   Single post — tags, comments, prev/next
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-post-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: var(--iwon-read-width);
  margin-top: 36px;
  padding-top: 24px;
  border-top: 1px solid var(--iwon-border-2);
}

body.iwon-page .iwon-post-tags-label {
  font-family: var(--iwon-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--iwon-text-faint);
  margin-right: 4px;
}

body.iwon-page .iwon-post-tags a {
  font-size: 12.5px;
  color: var(--iwon-text-muted);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--iwon-border-3);
  border-radius: var(--iwon-radius-sm);
  padding: 5px 10px;
  transition: color 0.15s ease, border-color 0.15s ease;
}

body.iwon-page .iwon-post-tags a:hover {
  color: var(--iwon-text);
  border-color: var(--iwon-blue-light);
}

body.iwon-page .iwon-comments {
  max-width: var(--iwon-read-width);
  margin-top: 46px;
  padding-top: 30px;
  border-top: 1px solid var(--iwon-border);
}

body.iwon-page .iwon-comments .iwon-section-label { margin-bottom: 16px; }

body.iwon-page .iwon-comment {
  background: var(--iwon-glass-bg);
  border: 1px solid var(--iwon-glass-border);
  border-radius: var(--iwon-radius);
  padding: 18px 20px;
  margin-bottom: 10px;
}

body.iwon-page .iwon-comment-meta {
  font-family: var(--iwon-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--iwon-text-faint);
  margin-bottom: 10px;
}

body.iwon-page .iwon-comment-body {
  font-size: 14px;
  color: var(--iwon-text-dim);
  line-height: 1.7;
}

body.iwon-page .iwon-comment-body p { margin: 0 0 0.8em; }
body.iwon-page .iwon-comment-body p:last-child { margin-bottom: 0; }

body.iwon-page .iwon-post-nav {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-top: 46px;
}

body.iwon-page .iwon-post-nav-link { display: block; }

body.iwon-page .iwon-post-nav-link .iwon-card-tag { display: block; }

body.iwon-page .iwon-post-nav-title {
  display: block;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.4;
  color: var(--iwon-text);
}

/* When there is only a Next, it still belongs in the right-hand column. */
body.iwon-page .iwon-post-nav-link--next {
  text-align: right;
  grid-column: 2;
}

/* --------------------------------------------------------------------------
   Header / nav
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 26px var(--iwon-gutter);
  border-bottom: 1px solid var(--iwon-border);
  position: sticky;
  top: 0;
  background: rgba(10, 13, 16, 0.85);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  z-index: 50;
}

body.iwon-page .iwon-logo {
  font-family: var(--iwon-font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.5px;
  color: var(--iwon-text);
}

body.iwon-page .iwon-logo span { color: var(--iwon-blue-light); }

/* Image logo (iwon-logo-2.png, a 196x60 reverse mark).
 *
 * 40px tall is deliberate: it is exactly the height of the nav's CTA button,
 * which was ALREADY the tallest thing in the bar. So on desktop the image
 * costs no extra header height at all — measured 93px before and after.
 *
 * Below 860px the CTA is hidden and the logo becomes the tallest element, so
 * it steps down to 34px to keep the mobile bar compact. The mobile menu's
 * sticky offset is tied to that number — see .iwon-mobile-menu. */
body.iwon-page .iwon-logo--img {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

body.iwon-page .iwon-logo-img {
  display: block;
  height: 40px;
  width: auto;
}

body.iwon-page .iwon-footer-brand .iwon-logo-img { height: 46px; }

@media (max-width: 860px) {
  body.iwon-page .iwon-logo-img { height: 34px; }
}

body.iwon-page .iwon-nav-links {
  display: flex;
  gap: 30px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Task 2 (2026-11-12): the extra "Services" item no longer fits the bar
   just above the 860px breakpoint (labels wrapped, then the page scrolled
   sideways). 861-1060px uses the hamburger + slide-out menu, which is not
   width-gated; 1061-1240px keeps the bar with a tighter gap. The 860px rules
   (logo size, hero grid etc.) are unchanged. */
@media (min-width: 861px) and (max-width: 1060px) {
  body.iwon-page .iwon-nav-links,
  body.iwon-page .iwon-nav > .iwon-nav-cta { display: none; }
  body.iwon-page .iwon-nav .iwon-hamburger { display: flex; }
}
@media (min-width: 1061px) and (max-width: 1240px) {
  body.iwon-page .iwon-nav-links { gap: 16px; }
}

body.iwon-page .iwon-nav-links a {
  color: var(--iwon-text-nav);
  font-size: 13.5px;
  font-weight: 500;
  transition: color 0.15s ease;
}

body.iwon-page .iwon-nav-links a:hover,
body.iwon-page .iwon-nav-links .current-menu-item > a { color: var(--iwon-text); }

body.iwon-page .iwon-nav-cta {
  background: var(--iwon-blue);
  color: #fff;
  font-family: var(--iwon-font-display);
  font-weight: 600;
  font-size: 13px;
  padding: 10px 18px;
  border-radius: var(--iwon-radius-sm);
  border: none;
  box-shadow: 0 0 18px rgba(45, 108, 223, 0.3);
  cursor: pointer;
  display: inline-block;
  transition: background 0.15s ease;
}

body.iwon-page .iwon-nav-cta:hover { background: var(--iwon-blue-light); }

body.iwon-page .iwon-hamburger {
  display: none;
  flex-direction: column;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
}

body.iwon-page .iwon-hamburger span {
  width: 22px;
  height: 2px;
  background: var(--iwon-text);
  display: block;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Animated close state */
body.iwon-page .iwon-hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.iwon-page .iwon-hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
body.iwon-page .iwon-hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

body.iwon-page .iwon-mobile-menu {
  display: none;
  flex-direction: column;
  gap: 18px;
  padding: 22px var(--iwon-gutter) 26px;
  border-bottom: 1px solid var(--iwon-border);
  background: var(--iwon-bg);
  position: sticky;
  /* MUST equal the MOBILE nav's height, or the panel either overlaps the bar
     it drops out of or floats below it. Below 860px the CTA is hidden, so the
     bar is 26px padding + the 34px logo + 26px padding + its 1px border = 87px.
     Measured, not derived: it read 77px against a 27px text logo whose bar was
     actually 80px, so it was already 3px out before the logo swap. Re-measure
     if either the nav padding or .iwon-logo-img's mobile height changes. */
  top: 87px;
  z-index: 49;
  list-style: none;
  margin: 0;
}

body.iwon-page .iwon-mobile-menu.iwon-open { display: flex; }
body.iwon-page .iwon-mobile-menu a { color: var(--iwon-text-nav); font-size: 14px; }
body.iwon-page .iwon-mobile-menu a:hover { color: var(--iwon-text); }

/* The mobile menu's <ul> comes from wp_nav_menu, so it needs its own list
   reset — without this it renders with default bullets and indentation. */
body.iwon-page .iwon-mobile-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
  width: 100%;
}

/* Desktop "Solutions" dropdown.
 *
 * Scoped to `> li.menu-item-has-children` so it only touches the one item
 * with children — every other top-level link keeps its current markup and
 * styling untouched. The submenu is `position: absolute`, so it never
 * affects the flow of `.iwon-nav-links`' own flex layout: no other nav item
 * shifts when it opens or closes.
 *
 * Shown on :hover for mouse/touch and :focus-within for keyboard users
 * tabbing through the child links — both must open it, since a keyboard
 * user tabbing to a child link never triggers :hover on the parent <li>.
 */
body.iwon-page .iwon-nav-links > li.menu-item-has-children {
  position: relative;
}

body.iwon-page .iwon-nav-links > li.menu-item-has-children > .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin: 14px 0 0;
  padding: 10px;
  min-width: 260px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /*
   * NOT --iwon-glass-bg. That token is a near-transparent white wash
   * (2.5% opacity) designed for cards that sit on the flat --iwon-bg page
   * background — here the panel instead overlays the hero, whose heading
   * text and network canvas showed straight through it. Same fix already
   * used one rule up: `.iwon-nav` itself is `rgba(10, 13, 16, 0.85)` (the
   * --iwon-bg color, not the glass-white one) precisely because it's the
   * other element on this page that has to read solid over the hero.
   * 0.97 plus the blur below leaves it opaque enough that no text
   * underneath is ever legible through the panel.
   */
  background: rgba(10, 13, 16, 0.97);
  border: 1px solid var(--iwon-glass-border);
  border-radius: var(--iwon-radius);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s ease;
  z-index: 60;
}

body.iwon-page .iwon-nav-links > li.menu-item-has-children:hover > .sub-menu,
body.iwon-page .iwon-nav-links > li.menu-item-has-children:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

body.iwon-page .iwon-nav-links .sub-menu a {
  display: block;
  padding: 9px 12px;
  border-radius: var(--iwon-radius-sm);
  white-space: nowrap;
  font-size: 13px;
}

body.iwon-page .iwon-nav-links .sub-menu a:hover,
body.iwon-page .iwon-nav-links .sub-menu a:focus {
  background: rgba(255, 255, 255, 0.05);
  color: var(--iwon-text);
}

/* Mobile "Solutions" children — rendered inline and indented under the
 * parent link, always visible. No JS, no accordion: depth 2 means
 * wp_nav_menu() already emits this nested <ul class="sub-menu"> in the
 * markup, so being visible by default is the entire implementation. */
body.iwon-page .iwon-mobile-links .sub-menu {
  list-style: none;
  margin: 14px 0 0;
  padding: 0 0 0 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  border-left: 1px solid var(--iwon-border);
  width: 100%;
}

body.iwon-page .iwon-mobile-links .sub-menu a {
  font-size: 13px;
  color: var(--iwon-text-nav);
}

body.iwon-page .iwon-mobile-links .sub-menu a:hover { color: var(--iwon-text); }

/* Group label inside a dropdown ("Website add-ons" under Services). Set by the
 * `iwon-nav-group-label` menu-item class; iwon_nav_group_label_atts() drops the
 * href, so this is text, not a link. */
body.iwon-page .iwon-nav-links .sub-menu .iwon-nav-group-label > a,
body.iwon-page .iwon-mobile-links .sub-menu .iwon-nav-group-label > a {
  cursor: default;
  font-family: var(--iwon-font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--iwon-text-muted);
  background: none;
}
body.iwon-page .iwon-nav-links .sub-menu .iwon-nav-group-label {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--iwon-border);
}

/* A dropdown that STARTS with a group label ("Popular" / "More" under
 * Solutions) is split into two columns, one per group, so it never runs past
 * the bottom of a laptop screen (16 rows were ~670px tall). Column 1 = the
 * first label and its links, column 2 = the second label and everything after
 * it; `dense` stacks each column from the top whatever the group sizes.
 * Services is not affected (its label is not the first item). max-height +
 * scroll is the fallback for very short windows. */
body.iwon-page .iwon-nav-links > li.menu-item-has-children > .sub-menu {
  max-height: calc(100vh - 90px);
  overflow-y: auto;
}
body.iwon-page .iwon-nav-links > li.menu-item-has-children > .sub-menu:has(> .iwon-nav-group-label:first-child) {
  display: grid;
  grid-template-columns: auto auto;
  grid-auto-flow: row dense;
  align-content: start;
  column-gap: 14px;
  row-gap: 2px;
}
body.iwon-page .iwon-nav-links .sub-menu:has(> .iwon-nav-group-label:first-child) > li {
  grid-column: 1;
}
body.iwon-page .iwon-nav-links .sub-menu:has(> .iwon-nav-group-label:first-child) > .iwon-nav-group-label:not(:first-child),
body.iwon-page .iwon-nav-links .sub-menu:has(> .iwon-nav-group-label:first-child) > .iwon-nav-group-label:not(:first-child) ~ li {
  grid-column: 2;
}
body.iwon-page .iwon-nav-links .sub-menu:has(> .iwon-nav-group-label:first-child) > .iwon-nav-group-label {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-footer {
  margin-top: 90px;
  border-top: 1px solid var(--iwon-border);
  padding: 56px var(--iwon-gutter) 30px;
}

body.iwon-page .iwon-footer-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1fr 1fr;
  gap: 30px;
  padding-bottom: 40px;
}

body.iwon-page .iwon-footer-tagline {
  font-size: 12.5px;
  color: var(--iwon-text-dimmer);
  line-height: 1.6;
  max-width: 240px;
  margin-top: 12px;
}

body.iwon-page .iwon-footer-col-title {
  font-family: var(--iwon-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.5px;
  color: var(--iwon-text-faint);
  text-transform: uppercase;
  margin-bottom: 16px;
}

body.iwon-page .iwon-footer-brand .iwon-logo { display: inline-block; }

/* Both the hand-authored <ul> and the wp_nav_menu-generated one. */
body.iwon-page .iwon-footer-col ul,
body.iwon-page .iwon-footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
}

body.iwon-page .iwon-footer-col a {
  display: block;
  color: var(--iwon-text-muted);
  font-size: 13px;
  margin-bottom: 11px;
  transition: color 0.15s ease;
}

body.iwon-page .iwon-footer-col a:hover { color: var(--iwon-text); }

body.iwon-page .iwon-footer-bottom {
  border-top: 1px solid var(--iwon-border);
  padding-top: 22px;
  display: flex;
  justify-content: space-between;
  font-size: 11.5px;
  color: var(--iwon-text-faint);
}

body.iwon-page .iwon-footer-bottom a { color: var(--iwon-text-faint); }
body.iwon-page .iwon-footer-bottom a:hover { color: var(--iwon-text-nav); }

/* --------------------------------------------------------------------------
   Scroll reveal

   FAILURE MODE THIS IS BUILT AROUND: a reveal system that hides content in CSS
   and un-hides it in JS will hide the entire page forever if the JS never runs.
   So the hidden state is gated on `html.iwon-anim`, a class iwon-ui.js sets
   from the <head> and ONLY when IntersectionObserver exists and the user has
   not asked for reduced motion. No JS, old browser, or reduce-motion => the
   class is absent, none of these rules match, and every element is simply
   visible with no transition. iwon-ui.js also has a belt-and-braces timeout
   that reveals anything still hidden after 4s.

   Setting the class in <head> (not on DOMContentLoaded) is what stops the
   flash of content appearing and then being hidden again.

   NO LAYOUT SHIFT: opacity and transform only. Every element occupies its
   final space from first paint; nothing here can move the document height.
   -------------------------------------------------------------------------- */

html.iwon-anim body.iwon-page { --iwon-stagger-scale: 1; }

/* The transition belongs on the element in BOTH states, so the reveal has
   something to animate along. It carries no opacity/transform values itself. */
html.iwon-anim body.iwon-page .iwon-section-label,
html.iwon-anim body.iwon-page .iwon-section-title,
html.iwon-anim body.iwon-page .iwon-section-intro,
html.iwon-anim body.iwon-page .iwon-section > p,
html.iwon-anim body.iwon-page .iwon-card,
html.iwon-anim body.iwon-page .iwon-step,
html.iwon-anim body.iwon-page .iwon-faq-item,
html.iwon-anim body.iwon-page .iwon-cta-band,
html.iwon-anim body.iwon-page .iwon-proof {
  transition:
    opacity 460ms cubic-bezier(0.22, 0.61, 0.24, 1),
    transform 460ms cubic-bezier(0.22, 0.61, 0.24, 1);
  transition-delay: calc(var(--iwon-reveal-delay, 0ms) * var(--iwon-stagger-scale, 1));
}

/*
 * The HIDDEN state carries :not(.iwon-revealed), rather than a separate
 * `.iwon-revealed { transform: none }` rule undoing it afterwards.
 *
 * That ordering matters. A revealed-state rule sits at (0,3,2), which
 * outranks `.iwon-card:hover` at (0,3,1) — so it would pin `transform: none`
 * and the hover lift would silently never apply, while border and shadow
 * still changed. Written this way, the moment an element is revealed these
 * declarations stop matching at all and `:hover` owns transform again with
 * no specificity fight.
 */
html.iwon-anim body.iwon-page .iwon-section-label:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-section-title:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-section-intro:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-section > p:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-card:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-step:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-faq-item:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-cta-band:not(.iwon-revealed),
html.iwon-anim body.iwon-page .iwon-proof:not(.iwon-revealed) {
  opacity: 0;
  transform: translateY(18px);
}

/*
 * Flow connectors ride the same reveal. Each line is a pseudo-element of its
 * step, so it needs its own hidden state: it fades and scales out FROM the
 * node (origin left / top) 180ms after the step itself starts revealing —
 * the node lands, then the line draws toward the next step, which is itself
 * arriving one stagger beat later. No JS addition: everything keys off the
 * .iwon-revealed class and the delay variable the observer already manages.
 */
html.iwon-anim body.iwon-page .iwon-step::after {
  transition:
    opacity 460ms cubic-bezier(0.22, 0.61, 0.24, 1),
    transform 460ms cubic-bezier(0.22, 0.61, 0.24, 1);
  transition-delay: calc(var(--iwon-reveal-delay, 0ms) * var(--iwon-stagger-scale, 1) + 180ms);
  transform-origin: left center;
}

html.iwon-anim body.iwon-page .iwon-step:not(.iwon-revealed)::after {
  opacity: 0;
  transform: scaleX(0);
}

/* Once an element has finished revealing, hand its transition back to the
   hover behaviour. Without this the 460ms reveal curve would still own
   `transform`, and the card lift on hover would crawl. iwon-ui.js adds this
   class on transitionend (with a timeout fallback). */
html.iwon-anim body.iwon-page .iwon-reveal-done {
  transition:
    border-color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
  transition-delay: 0ms;
}

/*
 * Hold the glass blur back until the reveal has finished.
 *
 * backdrop-filter is by far the most expensive property on these components,
 * and compositing it while simultaneously animating opacity on a dozen-plus
 * cards is what actually costs frames. Measured on the Solutions page during a
 * full-page scroll:
 *
 *   reveal on, blur throughout   mean 17.46ms,  4 frames >33ms, worst 50.0ms
 *   reveal on, blur deferred     mean 16.67ms,  0 frames >33ms, worst 16.8ms
 *   no motion at all (control)   mean 16.67ms,  0 frames >33ms, worst 16.8ms
 *
 * Deferring it puts the animated pages back on the no-motion baseline exactly.
 * Nothing is lost: the blur sits behind a card fading up from opacity 0 over a
 * near-black background, where it is imperceptible until the card is solid.
 */
html.iwon-anim body.iwon-page .iwon-card:not(.iwon-reveal-done),
html.iwon-anim body.iwon-page .iwon-faq-item:not(.iwon-reveal-done) {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* --------------------------------------------------------------------------
   Particle network accent — interior pages

   WHY THIS IS A GRID COLUMN AND NOT AN ABSOLUTELY POSITIONED BOX
   -------------------------------------------------------------
   It used to be `position: absolute; left: 100%; margin-left: 36px` on a
   720px-capped hero — i.e. a fixed 220px box pinned 36px past the text, with
   whatever space remained left over to its right. At 1440px that put a 220px
   graphic into 518px of free space with 262px of dead air after it, so it read
   as clinging to the text rather than occupying the space. The gap grew with
   the viewport: 312px of free space at 1200px, 931px at 1920px, so no fixed
   margin could centre it at more than one width.

   Making the hero a two-column grid removes the arithmetic entirely. The text
   keeps its 720px measure as the first column; the canvas takes the rest and
   is centred in it by definition, at every width. It also means the canvas can
   be fluid — it fills its column instead of being a fixed square.

   Scoped with :has() so the hundreds of heroes WITHOUT a network (every other
   page, every archive, the 404) keep the plain block layout they have today.
   -------------------------------------------------------------------------- */

body.iwon-page .iwon-page-hero { position: relative; }

body.iwon-page .iwon-page-hero:has(.iwon-network) {
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 720px) minmax(0, 1fr);
  align-items: center;
  gap: 48px;
}

/* The text column keeps the measure the hero used to enforce itself. Applies
   even where there is no network, which is harmless — the hero is still capped
   at 720px there, so this simply agrees with it. */
body.iwon-page .iwon-page-hero-text { max-width: 720px; }

body.iwon-page .iwon-network {
  pointer-events: none;
  opacity: 0.9;
}

body.iwon-page .iwon-network--light {
  width: 100%;
  height: 230px;
}

body.iwon-page .iwon-network canvas {
  display: block;
}

@media (min-width: 1500px) {
  body.iwon-page .iwon-network--light { height: 260px; }
}

/* THE WIDTH GATE. Below 1200px the 720px text column leaves no clear space
   beside it, so the accent would collide with the copy. `display: none` here
   is also what the script reads as "do not build anything" — it measures the
   container and finds 0x0. Keeping the gate in CSS means there is one place
   that decides, and JS cannot disagree with the layout. */
@media (max-width: 1200px) {
  body.iwon-page .iwon-network--light { display: none; }

  /* ...and the hero goes back to a single column, so the text is not left
     sharing a grid with a hidden sibling. */
  body.iwon-page .iwon-page-hero:has(.iwon-network) {
    display: block;
    max-width: 720px;
  }
}

/* Below 1200px the 720px hero leaves no clear space beside it, so the accent
   would collide with the content edge. Off well before the 860px breakpoint
   the brief sets as the hard ceiling. */
@media (max-width: 1200px) {
  body.iwon-page .iwon-orb { display: none; }
}

/* --------------------------------------------------------------------------
   Responsive — breakpoints lifted verbatim from the mockups (860px / 520px)
   -------------------------------------------------------------------------- */

@media (max-width: 860px) {
  /* Reveal stays, stagger goes — on a narrow screen a grid is a single column,
     so staggered delays read as items arriving late rather than as a sequence. */
  html.iwon-anim body.iwon-page { --iwon-stagger-scale: 0; }

  body.iwon-page .iwon-nav-links,
  body.iwon-page .iwon-nav > .iwon-nav-cta { display: none; }

  body.iwon-page .iwon-hamburger { display: flex; }

  body.iwon-page .iwon-hero {
    grid-template-columns: 1fr;
    min-height: auto;
  }

  body.iwon-page .iwon-canvas-wrap {
    height: 280px;
    order: -1;
  }

  body.iwon-page .iwon-headline { font-size: 32px; }
  body.iwon-page .iwon-page-title { font-size: 28px; }

  body.iwon-page .iwon-grid { grid-template-columns: repeat(2, 1fr); }
  body.iwon-page .iwon-grid--2 { grid-template-columns: 1fr; }

  /*
   * Flow steps stack as a vertical timeline: one column, the node moves to
   * the left of its text (a 2×2 flow would zigzag the sequence), and the
   * connector becomes a vertical rail dropping from each disc to the next.
   * Rail x = 21px = the disc's centre; text lives in the second column, so
   * the rail can never run through copy.
   */
  body.iwon-page .iwon-steps {
    grid-template-columns: 1fr;
    gap: 26px;
  }

  body.iwon-page .iwon-step {
    display: grid;
    grid-template-columns: 42px minmax(0, 1fr);
    column-gap: 16px;
  }

  body.iwon-page .iwon-step-num {
    grid-column: 1;
    grid-row: 1;
    margin: 0;
  }

  body.iwon-page .iwon-step-title {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
    margin: 0;
  }

  body.iwon-page .iwon-step-desc {
    grid-column: 2;
    grid-row: 2;
    margin-top: 6px;
  }

  body.iwon-page .iwon-step:not(:last-child)::after {
    top: 50px;                 /* 42px disc + 8px clearance */
    left: 20.5px;              /* disc centre minus half the line width */
    right: auto;
    bottom: -18px;             /* into the 26px row gap, 8px shy of the next disc */
    width: 1px;
    height: auto;
    background: linear-gradient(180deg, rgba(76, 140, 245, 0.5), rgba(76, 140, 245, 0.15));
  }

  /* The reveal draws the rail downward from the disc instead of sideways. */
  html.iwon-anim body.iwon-page .iwon-step::after { transform-origin: center top; }
  html.iwon-anim body.iwon-page .iwon-step:not(.iwon-revealed)::after { transform: scaleY(0); }

  body.iwon-page .iwon-footer-grid { grid-template-columns: 1fr 1fr; }

  body.iwon-page .iwon-footer-bottom {
    flex-direction: column;
    gap: 8px;
  }

  body.iwon-page .iwon-cta-band {
    flex-direction: column;
    align-items: flex-start;
  }

  /* Blog. The post-hero title needs its own entry here: the generic
     `.iwon-page-title` rule below 860px is (0,2,1) and cannot out-rank the
     `.iwon-post-hero .iwon-page-title` rule at (0,3,1). */
  body.iwon-page .iwon-post-hero .iwon-page-title { font-size: 27px; }

  body.iwon-page .iwon-post-grid,
  body.iwon-page .iwon-post-nav { grid-template-columns: 1fr; }

  body.iwon-page .iwon-post-nav-link--next {
    text-align: left;
    grid-column: auto;
  }

  body.iwon-page .iwon-article { font-size: 16px; }
  body.iwon-page .iwon-article h1,
  body.iwon-page .iwon-article h2 { font-size: 21px; }
  body.iwon-page .iwon-article h3 { font-size: 18px; }

  /* Floated images have nowhere to sit beside a single-column measure. */
  body.iwon-page .iwon-article .alignleft,
  body.iwon-page .iwon-article .alignright {
    float: none;
    margin: 1.9em auto;
  }
}

@media (max-width: 520px) {
  /* .iwon-steps is absent here on purpose: it already went single-column
     (timeline layout) at 860px above. */
  body.iwon-page .iwon-grid { grid-template-columns: 1fr; }

  body.iwon-page .iwon-pagination { gap: 6px; }

  body.iwon-page .iwon-pagination .page-numbers {
    padding: 8px 10px;
    min-width: 34px;
  }

  body.iwon-page .iwon-footer-grid {
    grid-template-columns: 1fr;
    gap: 26px;
  }

  body.iwon-page .iwon-cta-row { flex-direction: column; }

  body.iwon-page .iwon-nav,
  body.iwon-page .iwon-wrap,
  body.iwon-page .iwon-footer,
  body.iwon-page .iwon-mobile-menu {
    padding-left: 6vw;
    padding-right: 6vw;
  }
}

/* Respect reduced-motion preferences across the system */
@media (prefers-reduced-motion: reduce) {
  body.iwon-page *,
  body.iwon-page *::before,
  body.iwon-page *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  /* The ambient wash still paints, it just stops drifting. */
  body.iwon-page::before { animation: none !important; }

  /*
   * Reveal: iwon-ui.js does not add html.iwon-anim at all under reduced
   * motion, so the hidden state normally never applies. This is the second
   * line of defence for the one case JS cannot catch — a user turning the OS
   * setting on while the page is already open, after the class was set. The
   * media query re-evaluates live; without this, already-hidden sections
   * further down the page would never be revealed.
   */
  html.iwon-anim body.iwon-page .iwon-section-label,
  html.iwon-anim body.iwon-page .iwon-section-title,
  html.iwon-anim body.iwon-page .iwon-section-intro,
  html.iwon-anim body.iwon-page .iwon-section > p,
  html.iwon-anim body.iwon-page .iwon-card,
  html.iwon-anim body.iwon-page .iwon-step,
  html.iwon-anim body.iwon-page .iwon-step::after,
  html.iwon-anim body.iwon-page .iwon-faq-item,
  html.iwon-anim body.iwon-page .iwon-cta-band,
  html.iwon-anim body.iwon-page .iwon-proof {
    opacity: 1 !important;
    transform: none !important;
  }

  /* 3D accents are NOT hidden here. They follow the hero's existing
     reduced-motion contract: render one static frame and never start the
     animation loop. Reduced motion means remove the motion, not the artwork. */
}
