@charset "UTF-8";
/*!
 * Hot Web Design - template layer for the Joomla 6 "default" template.
 *
 * Cascade order (do not reorder - later layers intentionally win):
 *   1. Design tokens          7. Footer
 *   2. Base / reset           8. Utilities
 *   3. Typography             9. Responsive
 *   4. Layout & surfaces     10. Motion preferences
 *   5. Components            11. Print
 *   6. Joomla component views
 *
 * Theming. Every colour token below is declared once, as
 * light-dark(<light>, <dark>), and resolves against the element's
 * `color-scheme`. dark.css does nothing but flip that switch, plus the few
 * behaviours that are not colours (logo swap, icon swap). Components must
 * therefore consume tokens, never raw colours, and never repeat a rule per
 * theme.
 */

/* ============================================================
   1. DESIGN TOKENS
   ============================================================ */
:root {
  color-scheme: light;

  /*
   * -- The generated ramp -----------------------------------
   * index.php declares --hwd-n0..n3, --hwd-ink*, --hwd-contrast-* and
   * --hwd-accent-* inline on <html>, twice: a -lt set and a -dk set, both
   * worked out from the one colour the administrator picks.
   *
   * This block binds the light set only. It is what a browser without
   * light-dark() renders with - the light theme, always - and it is replaced
   * wholesale by the @supports block below everywhere else.
   *
   * The fallbacks are what the template renders with when it is loaded outside
   * a page that declares the ramp (the editor stylesheet, say).
   */
  --hwd-n0: var(--hwd-n0-lt, #fff);
  --hwd-n1: var(--hwd-n1-lt, #f7f8fc);
  --hwd-n2: var(--hwd-n2-lt, #f0f2f9);
  --hwd-n3: var(--hwd-n3-lt, #e2e5f1);
  --hwd-ink: var(--hwd-ink-lt, #5a585b);
  --hwd-ink-muted: var(--hwd-ink-muted-lt, #6b6970);
  --hwd-ink-strong: var(--hwd-ink-strong-lt, #0d0a46);
  --hwd-accent: var(--hwd-accent-lt, #6f40f1);
  --hwd-accent-hover: var(--hwd-accent-hover-lt, #5a33d1);
  --hwd-contrast-bg: var(--hwd-contrast-bg-lt, #0d0a46);
  --hwd-contrast-fg: var(--hwd-contrast-fg-lt, #b8bbc1);
  --hwd-contrast-head: var(--hwd-contrast-head-lt, #fff);
  --hwd-contrast-link: var(--hwd-contrast-link-lt, #b8bbc1);
  --hwd-primary: var(--hwd-primary-lt, #6f40f1);
  --hwd-primary-mid: var(--hwd-primary-mid-lt, #6f40f1);
  --hwd-primary-hover: var(--hwd-primary-hover-lt, #5a33d1);
  --hwd-on-accent: var(--hwd-on-accent-lt, #fff);
  --hwd-link-rgb: var(--hwd-link-rgb-lt, 111, 64, 241);
  --hwd-link-hover-rgb: var(--hwd-link-hover-rgb-lt, 90, 51, 209);

  /* Status colours are the one thing a theme cannot derive: they carry meaning,
     not brand. */
  --hwd-success: #1a7f4b;
  --hwd-warning: #b45309;
  --hwd-error: #b42318;
  --hwd-info: #0b5cad;

  /* The ink shadows are cast with. A near-black on the light page, pure black
     on the dark one - and much heavier there, because a dark ground swallows a
     faint shadow. */
  --hwd-shadow-ink-sm: color-mix(in srgb, var(--hwd-ink-strong) 6%, transparent);
  --hwd-shadow-ink: color-mix(in srgb, var(--hwd-ink-strong) 8%, transparent);
  --hwd-shadow-ink-lg: color-mix(in srgb, var(--hwd-ink-strong) 13%, transparent);
  --hwd-shadow-ink-modal: color-mix(in srgb, var(--hwd-ink-strong) 12%, transparent);

  /* -- Brand ------------------------------------------------ */
  --hwd-primary-gradient: linear-gradient(40deg, var(--hwd-primary) 0%, var(--hwd-primary-mid) 65%, var(--hwd-primary-hover) 100%);
  --hwd-primary-tint: color-mix(in srgb, var(--hwd-primary) 8%, transparent);
  --hwd-secondary: var(--hwd-contrast-bg);
  --hwd-dark: var(--hwd-contrast-bg);

  /* -- Surfaces --------------------------------------------- */
  --hwd-bg: var(--hwd-n0);
  --hwd-surface: var(--hwd-n0);
  --hwd-surface-2: var(--hwd-n1);
  --hwd-surface-3: var(--hwd-n2);
  --hwd-card-bg: var(--hwd-surface);
  /* Legacy alias: module HTML written against the previous stylesheet. */
  --hwd-bg-light: var(--hwd-surface-2);
  --hwd-overlay: color-mix(in srgb, var(--hwd-ink-strong) 65%, transparent);

  /* -- Text ------------------------------------------------- */
  --hwd-text: var(--hwd-ink);
  --hwd-heading: var(--hwd-ink-strong);
  --hwd-muted: var(--hwd-ink-muted);
  --hwd-accent-text: var(--hwd-accent);
  --hwd-link: var(--hwd-accent);
  --hwd-link-hover: var(--hwd-accent-hover);
  --hwd-btn-text: var(--hwd-on-accent);

  /* -- Lines ------------------------------------------------ */
  --hwd-border: var(--hwd-n3);
  --hwd-separator: var(--hwd-border);

  /* -- Header / menu surface --------------------------------
     Expressed against the page neutral, so the glass is the page colour at
     reduced opacity in both themes and needs no theme rule of its own. */
  --hwd-menu-bg: color-mix(in srgb, var(--hwd-n0) 84%, transparent);
  --hwd-menu-blur: saturate(180%) blur(10px);
  --hwd-menu-border: color-mix(in srgb, var(--hwd-ink-strong) 10%, transparent);
  --hwd-header-min-height: 82px;
  --hwd-hero-icon-size: 46px;

  /* -- Form controls ---------------------------------------- */
  --hwd-input-bg: var(--hwd-surface);
  --hwd-input-text: var(--hwd-text);
  --hwd-input-border: var(--hwd-border);
  --hwd-placeholder: var(--hwd-muted);

  /* -- Focus ------------------------------------------------ */
  --hwd-focus: var(--hwd-primary);
  --hwd-focus-width: 3px;
  --hwd-focus-offset: 2px;

  /* -- Radii ------------------------------------------------ */
  --hwd-radius-sm: 8px;
  --hwd-radius: 12px;
  --hwd-radius-lg: 16px;
  --hwd-radius-xl: 18px;
  --hwd-radius-pill: 999px;

  /* -- Elevation -------------------------------------------- */
  --hwd-shadow-sm: 0 6px 16px var(--hwd-shadow-ink-sm);
  --hwd-shadow: 0 12px 30px var(--hwd-shadow-ink);
  --hwd-shadow-lg: 0 18px 40px var(--hwd-shadow-ink-lg);
  --hwd-shadow-modal: 0 20px 60px var(--hwd-shadow-ink-modal);
  --hwd-shadow-header: 0 2px 20px var(--hwd-shadow-ink-sm);
  --hwd-shadow-brand: 0 10px 20px color-mix(in srgb, var(--hwd-primary) 20%, transparent);
  --hwd-shadow-brand-hover: 0 14px 28px color-mix(in srgb, var(--hwd-primary) 28%, transparent);

  /* -- Layout ----------------------------------------------- */
  --hwd-container: 1200px;
  --hwd-header-container: var(--hwd-container);
  --hwd-gutter: 15px;
  --hwd-gap: 30px;
  --hwd-section-y: 80px;
  --hwd-band-y: 64px;
  --hwd-sidebar-width: 300px;

  /* -- Typography ------------------------------------------- */
  --hwd-font-family-body: "Barlow", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --hwd-font-family-headings: var(--hwd-font-family-body);
  --hwd-font-family-display: "Poppins", var(--hwd-font-family-body);
  --hwd-font-weight-normal: 400;
  --hwd-font-weight-headings: 500;
  --hwd-line-height: 1.65;

  /* Heading scale. Fluid between phone and desktop, capped, and deliberately
     a step below Bootstrap's (40/32/28px): every heading on the site reads one
     of these, so the hierarchy is set in one place. */
  --hwd-h1-size: clamp(1.625rem, 1.3rem + 1.2vw, 2rem);
  --hwd-h2-size: clamp(1.375rem, 1.15rem + .8vw, 1.625rem);
  --hwd-h3-size: clamp(1.125rem, 1.05rem + .4vw, 1.25rem);
  --hwd-h4-size: 1.0625rem;
  --hwd-h5-size: 1rem;
  --hwd-h6-size: .9375rem;
  --hwd-scroll-margin-top: 6rem;

  /* -- Motion ------------------------------------------------
     Every transition on the site reads one of these, so a reduced-motion
     request is honoured by zeroing them (see section 10). */
  --hwd-transition: .2s ease;
  --hwd-transition-mid: .25s ease;
  --hwd-transition-fade: .5s ease;
  --hwd-transition-slow: .35s cubic-bezier(.2, 1, .3, 1);

  /* -- Stacking --------------------------------------------- */
  --hwd-z-header: 30;
  --hwd-z-backtop: 40;
  --hwd-z-dropdown: 50;
  --hwd-z-offcanvas: 90;
  --hwd-z-modal: 100;
  --hwd-z-skiplink: 110;
}

/*
 * The theme-aware bindings. Each token names its light and its dark value in
 * one place; which one applies is decided by `color-scheme` on <html>
 * (dark.css), and nowhere else.
 *
 * Gated so a browser without light-dark() keeps the light palette above
 * instead of losing every colour: a custom property is not validated when it
 * is declared, so a plain "declare twice" fallback would not work here.
 */
@supports (color: light-dark(#000, #fff)) {
  :root {
    --hwd-n0: light-dark(var(--hwd-n0-lt, #fff), var(--hwd-n0-dk, #0f0f0f));
    --hwd-n1: light-dark(var(--hwd-n1-lt, #f7f8fc), var(--hwd-n1-dk, #161618));
    --hwd-n2: light-dark(var(--hwd-n2-lt, #f0f2f9), var(--hwd-n2-dk, #1f2124));
    --hwd-n3: light-dark(var(--hwd-n3-lt, #e2e5f1), var(--hwd-n3-dk, #2e2e2e));
    --hwd-ink: light-dark(var(--hwd-ink-lt, #5a585b), var(--hwd-ink-dk, #d4d4d4));
    --hwd-ink-muted: light-dark(var(--hwd-ink-muted-lt, #6b6970), var(--hwd-ink-muted-dk, #a3a3a3));
    --hwd-ink-strong: light-dark(var(--hwd-ink-strong-lt, #0d0a46), var(--hwd-ink-strong-dk, #fff));
    --hwd-accent: light-dark(var(--hwd-accent-lt, #6f40f1), var(--hwd-accent-dk, #b9a5ff));
    --hwd-accent-hover: light-dark(var(--hwd-accent-hover-lt, #5a33d1), var(--hwd-accent-hover-dk, #d3c6ff));
    --hwd-contrast-bg: light-dark(var(--hwd-contrast-bg-lt, #0d0a46), var(--hwd-contrast-bg-dk, #2e2e2e));
    --hwd-contrast-fg: light-dark(var(--hwd-contrast-fg-lt, #b8bbc1), var(--hwd-contrast-fg-dk, #d4d4d4));
    --hwd-contrast-head: light-dark(var(--hwd-contrast-head-lt, #fff), var(--hwd-contrast-head-dk, #fff));
    --hwd-contrast-link: light-dark(var(--hwd-contrast-link-lt, #b8bbc1), var(--hwd-contrast-link-dk, #b9a5ff));
    --hwd-primary: light-dark(var(--hwd-primary-lt, #6f40f1), var(--hwd-primary-dk, #6f40f1));
    --hwd-primary-mid: light-dark(var(--hwd-primary-mid-lt, #6f40f1), var(--hwd-primary-mid-dk, #6f40f1));
    --hwd-primary-hover: light-dark(var(--hwd-primary-hover-lt, #5a33d1), var(--hwd-primary-hover-dk, #5a33d1));
    --hwd-on-accent: light-dark(var(--hwd-on-accent-lt, #fff), var(--hwd-on-accent-dk, #fff));

    /* The light values are too dark to read on a dark page. */
    --hwd-success: light-dark(#1a7f4b, #4ade80);
    --hwd-warning: light-dark(#b45309, #fbbf24);
    --hwd-error: light-dark(#b42318, #f87171);
    --hwd-info: light-dark(#0b5cad, #60a5fa);

    --hwd-shadow-ink-sm: light-dark(color-mix(in srgb, var(--hwd-ink-strong) 6%, transparent), rgb(0 0 0 / 45%));
    --hwd-shadow-ink: light-dark(color-mix(in srgb, var(--hwd-ink-strong) 8%, transparent), rgb(0 0 0 / 45%));
    --hwd-shadow-ink-lg: light-dark(color-mix(in srgb, var(--hwd-ink-strong) 13%, transparent), rgb(0 0 0 / 50%));
    --hwd-shadow-ink-modal: light-dark(color-mix(in srgb, var(--hwd-ink-strong) 12%, transparent), rgb(0 0 0 / 60%));
  }
}

/* Container width modifiers (body class from the template parameter or the
   per-menu-item override). */
.is-small { --hwd-container: 960px; }
.is-medium { --hwd-container: 1200px; }
.is-large { --hwd-container: 1480px; }
.is-xlarge { --hwd-container: 1680px; }
.is-full { --hwd-container: none; }

/* A 15px gutter is comfortable at desk widths and tight on a phone, where the
   text ends up pressed against the screen edge. Raising the token rather than
   padding individual blocks keeps every section on the same margin - which is
   the whole point of having one. */
@media (max-width: 767.98px) {
  :root { --hwd-gutter: 24px; }
}

/* ============================================================
   2. BASE / RESET
   ============================================================ */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  /* Nothing may scroll the page sideways - not even a submenu that opens
     before the deferred user.js has slid it back inside (see Dropdowns).
     `clip` propagates to the viewport as `hidden` but creates no scroll
     container of its own, so the sticky header is unaffected. */
  overflow-x: clip;
  background: var(--hwd-bg);
  color: var(--hwd-text);
  font-family: var(--hwd-font-family-body);
  line-height: var(--hwd-line-height);
}

img,
svg,
video { max-width: 100%; }

/* `height: auto` together with the width/height attributes is what preserves the
   intrinsic ratio while the image loads, and therefore what prevents layout
   shift (CLS). It is deliberately kept at element specificity so component
   rules - cards, heroes, avatars - can still size their own media. */
img,
video { height: auto; }

:target { scroll-margin-top: var(--hwd-scroll-margin-top); }

/* Single, visible focus indicator for every interactive element. Never remove
   this without providing an equally visible replacement. The outline follows
   the element's own corners; no radius is imposed here, because a square
   control that turned round on focus read as a glitch. */
:focus-visible {
  outline: var(--hwd-focus-width) solid var(--hwd-focus);
  outline-offset: var(--hwd-focus-offset);
}

/* Fallback for the error page, which loads this file without template.css. */
.visually-hidden:not(:focus):not(:active) {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Inline SVG icons drawn by the template chrome. They size with the text they
   sit in and take its colour. */
.hwd-icon {
  display: inline-block;
  flex: none;
  width: 1em;
  height: 1em;
  vertical-align: -.125em;
}

/* Skip link - visible only while focused, then pinned to the top of the page. */
.hwd-skip-link {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: var(--hwd-z-skiplink);
  transform: translateY(-120%);
  padding: 12px 20px;
  background: var(--hwd-primary);
  color: var(--hwd-on-accent);
  font-weight: 600;
  border-end-end-radius: var(--hwd-radius);
  transition: transform var(--hwd-transition);
}

.hwd-skip-link:focus {
  transform: translateY(0);
  color: var(--hwd-on-accent);
}

/* ============================================================
   3. TYPOGRAPHY
   ============================================================ */
h1, h2, h3, h4, h5, h6 {
  margin: 0 0 .5em;
  color: var(--hwd-heading);
  font-family: var(--hwd-font-family-headings);
  font-weight: var(--hwd-font-weight-headings);
  line-height: 1.2;
  text-wrap: balance;
}

h1, .h1 { font-size: var(--hwd-h1-size); }
h2, .h2 { font-size: var(--hwd-h2-size); }
h3, .h3 { font-size: var(--hwd-h3-size); }
h4, .h4 { font-size: var(--hwd-h4-size); }
h5, .h5 { font-size: var(--hwd-h5-size); }
h6, .h6 { font-size: var(--hwd-h6-size); }

a {
  color: var(--hwd-link);
  text-decoration: none;
}

a:hover { color: var(--hwd-link-hover); }

/*
 * Joomla's own reboot underlines every unclassed link (template.css:
 * `a:not([class])`, specificity 0,1,1) - which is the right default for prose
 * but wrong for navigation, buttons and cards, where a link is already obvious
 * from its position and shape.
 *
 * The chrome is named explicitly at the same specificity: later source order
 * wins, no !important is needed, and links inside article text keep their
 * underline.
 */
.hwd-skip-link,
.hwd-topbar a,
.hwd-header-top a,
.hwd-logo,
.hwd-menu a,
.hwd-dropdown a,
.hwd-mobile-nav a,
.hwd-header-actions a,
.hwd-lang-svg a,
.hwd-social a,
.hwd-contact a,
.hwd-btn,
.hwd-hero-icon,
.hwd-backtop,
.hwd-band a.hwd-btn,
.hwd-blog-grid__item .readmore a,
.hwd-sc-card a,
.hwd-sc-hero a,
.hwd-sc-links a,
.hwd-sc-children a,
.hwd-ab-cat,
.hwd-ab-share-icons a,
.hwd-ab-pagination a,
.hwd-footer a,
.hwd-copyright a { text-decoration: none; }

/* Chrome links are never underlined on hover - they are identified by their
   position and shape, not by colour, and the underline read as noise on the
   navigation. Focus keeps its underline: a keyboard user has no hover state,
   so this is the one place the cue still has to carry WCAG 1.4.1. */
.hwd-menu a:focus-visible,
.hwd-dropdown a:focus-visible,
.hwd-mobile-nav a:focus-visible,
.hwd-topbar a:focus-visible,
.hwd-footer a:focus-visible,
.hwd-copyright a:focus-visible,
.hwd-sc-links a:focus-visible,
.hwd-ab-pagination a:focus-visible { text-decoration: underline; }

/* ============================================================
   4. LAYOUT & SURFACES
   ============================================================ */
.hwd-container {
  width: 100%;
  max-width: var(--hwd-container);
  margin-inline: auto;
  padding-inline: var(--hwd-gutter);
  transition: max-width var(--hwd-transition);
}

/* Simple 12-column grid used by the module chromes. */
.hwd-module-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--hwd-gap);
}

.hwd-module-col {
  grid-column: span var(--hwd-module-span, 12);
  min-width: 0;
}

/* Legacy flex row helpers, kept for module HTML that already uses them. */
.hwd-row {
  display: flex;
  flex-wrap: wrap;
  margin-inline: calc(var(--hwd-gutter) * -1);
}

.hwd-row > * { padding-inline: var(--hwd-gutter); }
.hwd-col-4 { flex: 0 0 33.3333%; max-width: 33.3333%; }

/* Component + sidebars ------------------------------------- */
.hwd-grid {
  max-width: var(--hwd-container);
  margin-inline: auto;
  padding: 40px var(--hwd-gutter);
}

.hwd-grid-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}

body.has-sidebar-left .hwd-grid-main {
  grid-template-columns: minmax(0, var(--hwd-sidebar-width)) minmax(0, 1fr);
}

body.has-sidebar-right .hwd-grid-main {
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--hwd-sidebar-width));
}

body.has-sidebar-left.has-sidebar-right .hwd-grid-main {
  grid-template-columns: minmax(0, var(--hwd-sidebar-width)) minmax(0, 1fr) minmax(0, var(--hwd-sidebar-width));
}

.hwd-grid-banner { grid-column: 1 / -1; }

.hwd-component {
  min-width: 0;
  padding: 24px;
  border-radius: var(--hwd-radius);
  background: var(--hwd-surface);
}

.hwd-sidebar-left,
.hwd-sidebar-right { min-width: 0; }

/* Full-width sections and module bands --------------------- */
.hwd-section { padding-block: var(--hwd-section-y); }
.hwd-section-light { background: var(--hwd-surface); }

.hwd-section-head {
  max-width: 720px;
  margin: 0 auto 48px;
  text-align: center;
}

.hwd-section-head h2 { margin-bottom: 12px; }

.hwd-section-head p { color: var(--hwd-text); }

.hwd-band {
  width: 100%;
  padding-block: var(--hwd-band-y);
}

.hwd-band h1,
.hwd-band h2,
.hwd-band h3,
.hwd-band h4,
.hwd-band h5,
.hwd-band h6,
.hwd-band p { color: inherit; }

.hwd-band .moduletable,
.hwd-band .module { margin: 0; }

.hwd-band-title { color: inherit; }

/* ------------------------------------------------------------
   Surface roles

   A section names a role - page, soft, muted, contrast, brand - and the role
   resolves against the generated ramp. Two things follow from that:

   1. There is no colour here. Every value is a step of the ramp, and the ramp
      is generated from the one colour the administrator picks, once per theme.
      The theme flips the ramp and every role moves with it.

   2. A role re-scopes the whole token set for its subtree, not just background
      and colour. Without that, a heading inside a section would keep reading
      the *page's* --hwd-heading, and a light section in the dark theme would
      paint white text on a light surface. Everything a component reads is
      measured against the surface it is actually sitting on.
   ------------------------------------------------------------ */
.hwd-surface-soft,
.hwd-surface-muted,
.hwd-surface-contrast,
.hwd-surface-brand {
  background: var(--hwd-surface-bg);
  color: var(--hwd-surface-fg);

  --hwd-bg: var(--hwd-surface-bg);
  --hwd-surface: var(--hwd-surface-raised);
  --hwd-surface-2: var(--hwd-surface-raised-2);
  --hwd-surface-3: var(--hwd-surface-raised-3);
  --hwd-card-bg: var(--hwd-surface-raised);
  --hwd-bg-light: var(--hwd-surface-raised-2);
  --hwd-text: var(--hwd-surface-fg);
  --hwd-heading: var(--hwd-surface-head);
  --hwd-muted: color-mix(in srgb, var(--hwd-surface-fg) 74%, var(--hwd-surface-bg));
  --hwd-border: color-mix(in srgb, var(--hwd-surface-fg) 18%, var(--hwd-surface-bg));
  --hwd-separator: var(--hwd-border);
  --hwd-link: var(--hwd-surface-link);
  --hwd-link-hover: var(--hwd-surface-head);
  --hwd-accent-text: var(--hwd-surface-link);
  --hwd-input-bg: var(--hwd-surface-raised);
  --hwd-input-text: var(--hwd-surface-fg);
  --hwd-input-border: var(--hwd-border);
  --hwd-placeholder: var(--hwd-muted);
  --hwd-focus: var(--hwd-surface-link);
}

/* The page role paints nothing: it *is* the page, and re-scoping it would only
   restate what :root already says. */
.hwd-surface-page { background: transparent; }

/*
 * Whichever element carries the role owns the surface.
 *
 * Markup that paints a band of its own - a module wrapped in a section utility,
 * or the hero with its vertical fade - was written when a section had to supply
 * its own background. Nested inside a role it has to defer, or the choice made
 * in the back end is silently overruled by the content.
 *
 * `page` is excluded on purpose: it paints nothing, so there is nothing to
 * defer to and the hero keeps the gradient it was designed with.
 */
:is(.hwd-surface-soft, .hwd-surface-muted, .hwd-surface-contrast, .hwd-surface-brand)
  :is(.hwd-section, .hwd-section-light, .hwd-hero) {
  background: transparent;
}

/* A band also owns the vertical rhythm, so a section nested in one must not add
   its padding on top. The hero is left alone: its height is the design. */
.hwd-band :is(.hwd-section, .hwd-section-light) { padding-block: 0; }

/* Elevation reads as "lighter" in both themes - a card lifts off a white page
   and off a near-black one alike - so a raised step always moves toward n0 in
   the light theme and away from it in the dark one. The ramp already encodes
   that direction, so a role only has to name the neighbouring steps. */
.hwd-surface-soft {
  --hwd-surface-bg: var(--hwd-n1);
  --hwd-surface-fg: var(--hwd-ink);
  --hwd-surface-head: var(--hwd-ink-strong);
  --hwd-surface-link: var(--hwd-accent);
  --hwd-surface-raised: var(--hwd-n0);
  --hwd-surface-raised-2: var(--hwd-n2);
  --hwd-surface-raised-3: var(--hwd-n3);
}

.hwd-surface-muted {
  --hwd-surface-bg: var(--hwd-n2);
  --hwd-surface-fg: var(--hwd-ink);
  --hwd-surface-head: var(--hwd-ink-strong);
  --hwd-surface-link: var(--hwd-accent);
  --hwd-surface-raised: var(--hwd-n0);
  --hwd-surface-raised-2: var(--hwd-n1);
  --hwd-surface-raised-3: var(--hwd-n3);
}

.hwd-surface-contrast {
  --hwd-surface-bg: var(--hwd-contrast-bg);
  --hwd-surface-fg: var(--hwd-contrast-fg);
  --hwd-surface-head: var(--hwd-contrast-head);
  --hwd-surface-link: var(--hwd-contrast-link);
  --hwd-surface-raised: color-mix(in srgb, var(--hwd-contrast-bg) 92%, var(--hwd-contrast-head));
  --hwd-surface-raised-2: color-mix(in srgb, var(--hwd-contrast-bg) 86%, var(--hwd-contrast-head));
  --hwd-surface-raised-3: color-mix(in srgb, var(--hwd-contrast-bg) 80%, var(--hwd-contrast-head));
}

.hwd-surface-brand {
  --hwd-surface-bg: var(--hwd-primary);
  --hwd-surface-fg: var(--hwd-on-accent);
  --hwd-surface-head: var(--hwd-on-accent);
  --hwd-surface-link: var(--hwd-on-accent);
  --hwd-surface-raised: color-mix(in srgb, var(--hwd-primary) 88%, var(--hwd-on-accent));
  --hwd-surface-raised-2: color-mix(in srgb, var(--hwd-primary) 80%, var(--hwd-on-accent));
  --hwd-surface-raised-3: color-mix(in srgb, var(--hwd-primary) 72%, var(--hwd-on-accent));
  background: var(--hwd-primary-gradient);
}

/* ============================================================
   5. COMPONENTS
   ============================================================ */

/* -- Top bar ----------------------------------------------- */
/* The HotWebDesign header carries the contact details itself, so the top bar
   only appears when a module is actually published to one of its positions. */
.hwd-topbar {
  padding-block: 6px;
  font-size: .8125rem;
}

/* Two equal halves rather than "as wide as their content": the split stays put
   whatever each side holds, so the right-hand group never drifts left when the
   left-hand one is short. */
.hwd-topbar-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 16px;
}

.hwd-topbar a { color: inherit; }
.hwd-topbar a:hover,
.hwd-topbar a:focus-visible { color: var(--hwd-link); }

.hwd-topbar-left,
.hwd-topbar-right {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  min-width: 0;
}

.hwd-topbar-right { justify-content: flex-end; }

/* On a phone the two halves stack; equal columns would leave each one too
   narrow to hold a phone number or an address. */
@media (max-width: 575.98px) {
  .hwd-topbar-inner { grid-template-columns: 1fr; }
  .hwd-topbar-left,
  .hwd-topbar-right { justify-content: center; }
}

/* -- header-top strip -------------------------------------- */
.hwd-header-top {
  width: 100%;
}

.hwd-header-top-inner,
.hwd-header-top .mod-custom,
.hwd-header-top .moduletable {
  width: 100%;
  margin: 0;
  padding: 0;
  background: inherit;
  color: inherit;
}

.hwd-header-top a {
  color: inherit;
  transition: color var(--hwd-transition);
}

.hwd-header-top a:hover,
.hwd-header-top a:focus-visible { color: var(--hwd-link); }

/* -- Header ------------------------------------------------ */
/* The bar's own surface, and the only thing the "Header Background" option can
   paint: the sticky variants draw their glass on a pseudo layer above it. */
.hwd-header {
  position: relative;
  z-index: var(--hwd-z-header);
  background: var(--hwd-surface-bg, transparent);
  transition: background var(--hwd-transition-slow), box-shadow var(--hwd-transition-slow);
}

/* On the front page the header floats over the hero. */
.hwd-frontpage .hwd-header {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
}

/* Two cases where an opaque surface of its own would defeat the design: a
   header floating over the hero, and the two translucent sticky styles - both
   are meant to let what is behind them show through. */
.hwd-frontpage .hwd-header:not(.hwd-sticky),
body.hwd-sticky-glass .hwd-header.hwd-sticky,
body.hwd-sticky-transparent .hwd-header.hwd-sticky { background: transparent; }

.hwd-header.hwd-sticky {
  position: sticky;
  inset-block-start: 0;
}

/* The shadow is a scroll cue, not decoration: it says content has passed under
   the bar. At rest the header sits flush with the page, so it casts nothing.
   .is-scrolled is set by user.js; with no JavaScript the header simply never
   lifts, which is the correct resting state rather than a broken one. */
.hwd-header.hwd-sticky.is-scrolled { box-shadow: var(--hwd-shadow-header); }

/* The glass is painted on a pseudo layer: an element with backdrop-filter
   becomes a backdrop root, which would clip the blur of the dropdowns. */
.hwd-header.hwd-sticky::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--hwd-menu-bg);
  backdrop-filter: var(--hwd-menu-blur);
}

/* Sticky variants. Header and dropdowns read the same tokens, so the submenu
   always inherits the style selected in the template options. Every value is
   a mix of the page neutral, which is what makes them correct in both themes
   without a theme rule. */
body.hwd-sticky-solid {
  --hwd-menu-bg: var(--hwd-surface-bg, var(--hwd-n0));
  --hwd-menu-blur: none;
}

body.hwd-sticky-transparent {
  --hwd-menu-bg: color-mix(in srgb, var(--hwd-n0) 45%, transparent);
  --hwd-menu-blur: saturate(140%) blur(6px);
  --hwd-menu-border: transparent;
}

body.hwd-sticky-transparent .hwd-header.hwd-sticky { box-shadow: none; }

body.hwd-sticky-transparent .hwd-header:hover,
body.hwd-sticky-transparent .hwd-header:focus-within {
  --hwd-menu-bg: color-mix(in srgb, var(--hwd-n0) 92%, transparent);
  --hwd-menu-border: color-mix(in srgb, var(--hwd-n3) 60%, transparent);
}

.hwd-header-inner {
  /* The containing block of the multi-column submenus (see Dropdowns). */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: var(--hwd-header-min-height);
  max-width: var(--hwd-header-container);
}

/* The header is a three-slot row: brand, optional module content, navigation.
   Only the brand may absorb the leftover space - the controls on the right have
   a fixed footprint, so letting them shrink is what pushes the row off-screen. */
.hwd-header-logo {
  flex: 1 1 auto;
  min-width: 0;
}

/* Full-width strip for the "header" module position. */
.hwd-header-strip {
  width: 100%;
  font-size: .875rem;
}

.hwd-header-strip-inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 12px;
  padding-block: 6px;
}

.hwd-header-strip a { color: inherit; }
.hwd-header-strip a:hover,
.hwd-header-strip a:focus-visible { color: var(--hwd-link); }

.hwd-header-strip p,
.hwd-header-strip .mod-custom { margin: 0; }

.hwd-header-nav {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 16px;
  min-width: 0;
  margin-inline-start: auto;
}

.hwd-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.hwd-header-bottom { width: 100%; }

/* -- Logo -------------------------------------------------- */
.hwd-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--hwd-heading);
  font-family: var(--hwd-font-family-display);
  font-weight: 800;
  font-size: 1.375rem;
  letter-spacing: .02em;
}

.hwd-logo:hover { color: var(--hwd-heading); }

/* Both logo variants are in the markup so the swap needs no JavaScript and
   cannot shift the layout; only one is ever displayed (dark.css). A logo is
   sized by its height, so width:auto lets it shrink with the header instead
   of collapsing. */
.hwd-logo-img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 48px;
}
.hwd-logo-img--dark { display: none; }

.hwd-logo-tagline {
  margin-inline-start: 6px;
  color: var(--hwd-muted);
  font-size: .625rem;
  font-weight: 400;
  letter-spacing: .1em;
}

/* -- Primary navigation ------------------------------------ */
.hwd-nav { min-width: 0; }

.hwd-menu {
  display: flex;
  flex-direction: row;
  align-items: center;
  /* The links carry their own padding, so the list needs almost no gap. */
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-menu > li {
  position: relative;
  display: flex;
  align-items: center;
}

/*
 * A multi-column submenu is centred in the header bar, not under its item: a
 * panel up to 1480px wide centred on an item in the right half of the bar
 * runs off the screen on anything narrower than a large desktop. Making the
 * item static hands the panel to .hwd-header-inner as its containing block.
 */
.hwd-menu > :is(.hwd-columns-3, .hwd-columns-4, .hwd-columns-5, .hwd-columns-6) {
  position: static;
}

.hwd-menu > li > a,
.hwd-menu > li > .mod-menu__heading,
.hwd-menu > li > .mod-menu__separator {
  display: flex;
  align-items: center;
  /* No gap: icon-to-label spacing is set on the icon instead - see below. */
  gap: 0;
  min-height: var(--hwd-header-min-height);
  padding-inline: 10px;
  color: var(--hwd-heading);
  font-weight: 500;
  font-size: .9375rem;
  white-space: nowrap;
  transition: color var(--hwd-transition);
}

.hwd-menu > li > a:hover,
.hwd-menu > li.active > a,
.hwd-menu > li.current > a { color: var(--hwd-accent-text); }

/*
 * Menu icons.
 *
 * Core emits class="p-2 pt-0" on the icon span; those Bootstrap utilities are
 * !important, so a stylesheet cannot undo them. The mod_menu item layouts are
 * overridden in html/mod_menu/ to emit .hwd-menu-icon instead, which is why
 * this rule needs no !important of its own.
 *
 * A square, line-height:1 box is what actually centres the glyph against the
 * label: the previous padding (0 top, 8px bottom) left the glyph sitting in the
 * top of a taller box, so it read as too high even though the box was centred.
 */
.hwd-menu .hwd-menu-icon,
.hwd-menu .fas,
.hwd-menu .far,
.hwd-menu .fab,
.hwd-menu [class*=" fa-"] {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.25em;
  margin: 0;
  padding: 0;
  font-size: .9375rem;
  line-height: 1;
}

/*
 * Icon-to-label spacing sits on the icon, not on the parent's flex gap.
 *
 * Component items put the icon directly inside the link, so a gap works there.
 * Heading and separator parents nest it inside .mod-menu__heading, which is not
 * a flex container - so a parent gap spaced nothing and those items looked
 * cramped while the others did not. One rule on the icon covers both shapes.
 */
.hwd-menu > li > a > .hwd-menu-icon,
.hwd-menu > li > .mod-menu__toggle-sub .hwd-menu-icon {
  margin-inline-end: 7px;
}

/* Submenu toggle rendered next to a normal link. It sits in the flow beside
   the link rather than floating over its padding, so the item needs no
   positioning of its own - which is what lets the mega panels above escape it. */
.hwd-menu > li > .mod-menu__toggle-sub:not(:has(.mod-menu__heading, .mod-menu__separator)) {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 34px;
  margin-inline: -6px 4px;
  padding: 0;
  border: 0;
  background: transparent;
  color: currentcolor;
  cursor: pointer;
}

/* Submenu toggle that *is* the item (heading / separator parents). */
.hwd-menu > li > .mod-menu__toggle-sub:has(.mod-menu__heading, .mod-menu__separator) {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--hwd-header-min-height);
  padding-block: 0;
  padding-inline: 10px 25px;
  border: 0;
  background: transparent;
  color: var(--hwd-heading);
  font: 500 .9375rem/1.2 var(--hwd-font-family-body);
  cursor: pointer;
}

.hwd-menu > li > .mod-menu__toggle-sub .mod-menu__heading,
.hwd-menu > li > .mod-menu__toggle-sub .mod-menu__separator {
  padding: 0;
  color: inherit;
  font: inherit;
}

.hwd-menu > li > .mod-menu__toggle-sub:has(.mod-menu__heading, .mod-menu__separator) .hwd-caret {
  position: absolute;
  inset-inline-end: 8px;
}

.hwd-menu > .hwd-has-dropdown > a { padding-inline-end: 8px; }

.hwd-caret {
  width: 12px;
  height: 12px;
  vertical-align: middle;
  transition: transform var(--hwd-transition);
}

.hwd-has-dropdown[data-hwd-open] > .mod-menu__toggle-sub .hwd-caret,
.hwd-has-dropdown:hover > .mod-menu__toggle-sub .hwd-caret { transform: rotate(180deg); }

/* -- Dropdowns --------------------------------------------- */
.hwd-dropdown {
  position: absolute;
  inset-block-start: calc(100% - 8px);
  inset-inline-start: 0;
  z-index: var(--hwd-z-dropdown);
  display: none;
  min-width: 270px;
  margin: 0;
  padding: 12px;
  list-style: none;
  border: 1px solid var(--hwd-menu-border);
  border-radius: 14px;
  background: var(--hwd-menu-bg);
  backdrop-filter: var(--hwd-menu-blur);
  box-shadow: var(--hwd-shadow-lg);
  /* A very tall submenu must never trap its own content off-screen. */
  max-height: min(70vh, 720px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* user.js measures a panel that would run past the header container or the
     viewport and slides it back by this much, so it ends flush with the
     container edge like the mega panels; without script the panel simply sits
     under its item (and body { overflow-x: clip } keeps the page from
     scrolling sideways). */
  transform: translateX(var(--hwd-dropdown-shift, 0));
}

/* Only an explicit disclosure opens a submenu. Hover and focus are added back
   below, but only for real pointers: on a touch screen a tap leaves :hover
   stuck on the item, which is what makes an off-canvas menu feel jammed. */
.hwd-has-dropdown[data-hwd-open] > .hwd-dropdown { display: block; }

@media (hover: hover) and (pointer: fine) {
  .hwd-has-dropdown:hover > .hwd-dropdown,
  .hwd-has-dropdown:focus-within > .hwd-dropdown { display: block; }
}

/* Without script nothing can set data-hwd-open, so keyboard focus has to open
   the submenu on every device, not only for fine pointers. */
html.hwd-no-js .hwd-has-dropdown:focus-within > .hwd-dropdown { display: block; }

.hwd-dropdown li {
  position: relative;
  list-style: none;
}

.hwd-dropdown a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--hwd-radius-sm);
  color: var(--hwd-heading);
  font-size: .875rem;
  font-weight: 500;
  line-height: 1.35;
}

.hwd-dropdown a:hover,
.hwd-dropdown a:focus-visible {
  background: var(--hwd-surface-2);
  color: var(--hwd-accent-text);
}

.hwd-menu > li > .hwd-dropdown > li > a,
.hwd-menu > li > .hwd-dropdown > li > .mod-menu__heading,
.hwd-menu > li > .hwd-dropdown > li > .mod-menu__separator {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 14px;
  border-radius: var(--hwd-radius-sm);
}

.hwd-menu > li > .hwd-dropdown > li > a > img,
.hwd-menu > li > .hwd-dropdown > li > .mod-menu__heading > img,
.hwd-menu > li > .hwd-dropdown > li > .mod-menu__separator > img {
  flex: 0 0 52px;
  width: 52px;
  height: 52px;
  object-fit: contain;
}

.hwd-menu > li > .hwd-dropdown > li > a > .fas,
.hwd-menu > li > .hwd-dropdown > li > a > .far,
.hwd-menu > li > .hwd-dropdown > li > a > .fab,
.hwd-menu > li > .hwd-dropdown > li > a > .fa-solid,
.hwd-menu > li > .hwd-dropdown > li > a > .fa-regular,
.hwd-menu > li > .hwd-dropdown > li > a > .fa-brands {
  flex: 0 0 40px;
  width: 40px;
  padding-block: 4px;
  text-align: center;
  font-size: 1.875rem;
  line-height: 1;
}

.hwd-menu-copy {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.hwd-menu-title {
  color: var(--hwd-heading);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
}

.hwd-menu-subtext {
  color: var(--hwd-text);
  font-size: .8125rem;
  font-weight: 400;
  line-height: 1.45;
}

.hwd-dropdown a:hover .hwd-menu-title,
.hwd-dropdown a:focus-visible .hwd-menu-title { color: var(--hwd-accent-text); }

.hwd-dropdown .hwd-dropdown {
  inset-block-start: -12px;
  inset-inline-start: calc(100% + 10px);
}

/* Multi-column ("mega") submenus. Two columns stay under their item like a
   plain dropdown; three or more are centred in the header bar. */
.hwd-columns-2 > .hwd-dropdown,
.hwd-columns-3 > .hwd-dropdown,
.hwd-columns-4 > .hwd-dropdown,
.hwd-columns-5 > .hwd-dropdown,
.hwd-columns-6 > .hwd-dropdown {
  gap: 2px 12px;
  grid-auto-flow: row;
}

.hwd-columns-3 > .hwd-dropdown,
.hwd-columns-4 > .hwd-dropdown,
.hwd-columns-5 > .hwd-dropdown,
.hwd-columns-6 > .hwd-dropdown {
  inset-inline: var(--hwd-gutter);
  margin-inline: auto;
}

.hwd-columns-2[data-hwd-open] > .hwd-dropdown,
.hwd-columns-3[data-hwd-open] > .hwd-dropdown,
.hwd-columns-4[data-hwd-open] > .hwd-dropdown,
.hwd-columns-5[data-hwd-open] > .hwd-dropdown,
.hwd-columns-6[data-hwd-open] > .hwd-dropdown { display: grid; }

@media (hover: hover) and (pointer: fine) {
  .hwd-columns-2:hover > .hwd-dropdown,
  .hwd-columns-2:focus-within > .hwd-dropdown,
  .hwd-columns-3:hover > .hwd-dropdown,
  .hwd-columns-3:focus-within > .hwd-dropdown,
  .hwd-columns-4:hover > .hwd-dropdown,
  .hwd-columns-4:focus-within > .hwd-dropdown,
  .hwd-columns-5:hover > .hwd-dropdown,
  .hwd-columns-5:focus-within > .hwd-dropdown,
  .hwd-columns-6:hover > .hwd-dropdown,
  .hwd-columns-6:focus-within > .hwd-dropdown { display: grid; }
}

html.hwd-no-js .hwd-columns-2:focus-within > .hwd-dropdown,
html.hwd-no-js .hwd-columns-3:focus-within > .hwd-dropdown,
html.hwd-no-js .hwd-columns-4:focus-within > .hwd-dropdown,
html.hwd-no-js .hwd-columns-5:focus-within > .hwd-dropdown,
html.hwd-no-js .hwd-columns-6:focus-within > .hwd-dropdown { display: grid; }

.hwd-columns-2 > .hwd-dropdown { width: min(960px, calc(100vw - 2 * var(--hwd-gutter))); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hwd-columns-3 > .hwd-dropdown { width: min(1120px, calc(100% - 2 * var(--hwd-gutter))); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hwd-columns-4 > .hwd-dropdown { width: min(1240px, calc(100% - 2 * var(--hwd-gutter))); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hwd-columns-5 > .hwd-dropdown { width: min(1360px, calc(100% - 2 * var(--hwd-gutter))); grid-template-columns: repeat(5, minmax(0, 1fr)); }
.hwd-columns-6 > .hwd-dropdown { width: min(1480px, calc(100% - 2 * var(--hwd-gutter))); grid-template-columns: repeat(6, minmax(0, 1fr)); }

/* -- Header icon buttons ----------------------------------- */
.hwd-search-toggle,
.hwd-burger,
.hwd-dark-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--hwd-radius);
  background: var(--hwd-primary-tint);
  color: var(--hwd-accent-text);
  font-size: 1rem;
  cursor: pointer;
  transition: background var(--hwd-transition), color var(--hwd-transition), border-color var(--hwd-transition);
}

.hwd-search-toggle:hover,
.hwd-burger:hover,
.hwd-dark-toggle:hover {
  background: var(--hwd-primary);
  border-color: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

.hwd-burger {
  display: none;
  flex-direction: column;
  gap: 4px;
}

.hwd-burger span {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentcolor;
}

/* Theme toggle: one icon per state, driven by the resolved theme (dark.css
   swaps them). */
.hwd-dark-toggle .hwd-icon-sun { display: none; }
.hwd-dark-toggle .hwd-icon-moon { display: block; }

/* Neither control can do anything without script, so neither is shown. */
html.hwd-no-js .hwd-search-toggle,
html.hwd-no-js .hwd-dark-toggle { display: none; }

/* -- Search modal ------------------------------------------ */
.hwd-search-modal {
  position: fixed;
  inset: 0;
  z-index: var(--hwd-z-modal);
  display: flex;
  /* Anchored near the top rather than dead centre: a search dialog opens under
     the control that summoned it, and centring it makes the page jump. */
  align-items: flex-start;
  justify-content: center;
  padding: clamp(16px, 10vh, 120px) 20px 20px;
  background: color-mix(in srgb, var(--hwd-overlay) 92%, transparent);
  backdrop-filter: blur(3px);
}

.hwd-search-modal[hidden] { display: none; }

.hwd-search-modal-inner {
  width: min(620px, 100%);
  padding: 20px 22px 24px;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-lg);
  background: var(--hwd-surface);
  box-shadow: var(--hwd-shadow-modal);
}

.hwd-search-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-block-end: 14px;
}

.hwd-search-title {
  margin: 0;
  color: var(--hwd-heading);
  font-family: var(--hwd-font-family-headings);
  font-size: .9375rem;
  font-weight: 600;
}

.hwd-search-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The 44px target stays, but as a flex item it no longer overlaps anything. */
  width: 40px;
  height: 40px;
  margin-inline-end: -8px;
  border: 0;
  border-radius: var(--hwd-radius-pill);
  background: none;
  color: var(--hwd-muted);
  font-size: 1.125rem;
  cursor: pointer;
  transition: background var(--hwd-transition), color var(--hwd-transition);
}

@media (hover: hover) and (pointer: fine) {
  .hwd-search-close:hover {
    background: var(--hwd-surface-2);
    color: var(--hwd-heading);
  }
}

.hwd-search-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.hwd-search-form input[type="search"] {
  flex: 1 1 220px;
  min-width: 0;
  padding: 13px 16px;
  border: 1px solid var(--hwd-input-border);
  border-radius: var(--hwd-radius);
  background: var(--hwd-input-bg);
  color: var(--hwd-input-text);
  font: inherit;
  font-size: .9375rem;
}

/*
 * The global focus ring is an outline drawn 2px outside the element. On a
 * bordered input that reads as two stacked blue rings with a white gap between
 * them, which is what made this control look broken. One soft halo, tinted from
 * the brand colour, says the same thing once.
 *
 * The transparent outline is not decoration: forced-colours modes discard the
 * box-shadow, and it is the only thing left to render.
 */
.hwd-search-form input[type="search"]:focus-visible,
.hwd-search-form input[type="search"]:focus {
  outline: 2px solid transparent;
  outline-offset: 0;
  border-color: var(--hwd-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--hwd-primary) 22%, transparent);
}

.hwd-search-form button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  flex: 0 0 auto;
  padding: 13px 24px;
  border: 0;
  border-radius: var(--hwd-radius);
  background: var(--hwd-primary-gradient);
  color: var(--hwd-on-accent);
  font: inherit;
  font-size: .9375rem;
  font-weight: 600;
  cursor: pointer;
  transition: box-shadow var(--hwd-transition), transform var(--hwd-transition);
}

@media (hover: hover) and (pointer: fine) {
  .hwd-search-form button[type="submit"]:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 18px color-mix(in srgb, var(--hwd-primary) 30%, transparent);
  }
}

/* On a phone the button takes the full width under the field rather than
   squeezing both onto one line. */
@media (max-width: 479.98px) {
  .hwd-search-form input[type="search"] { flex: 1 1 100%; }
  .hwd-search-form button[type="submit"] { flex: 1 1 100%; }
}

/* -- Mobile navigation ------------------------------------- */
.hwd-mobile-nav {
  position: fixed;
  inset: 0;
  z-index: var(--hwd-z-offcanvas);
  display: flex;
  justify-content: flex-end;
  background: var(--hwd-overlay);
  backdrop-filter: blur(4px);
}

.hwd-mobile-nav[hidden] { display: none; }

.hwd-mobile-panel {
  position: relative;
  width: min(360px, 85vw);
  height: 100%;
  padding: 24px;
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--hwd-surface);
  box-shadow: var(--hwd-shadow-lg);
}

.hwd-mobile-close {
  position: absolute;
  inset-block-start: 14px;
  inset-inline-end: 14px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: none;
  color: var(--hwd-text);
  font-size: 1.25rem;
  cursor: pointer;
}

.hwd-mobile-logo {
  margin-block-end: 18px;
  color: var(--hwd-heading);
  font-weight: 800;
}

.hwd-mobile-body { min-width: 0; }

/* Inside the off-canvas the desktop menu becomes a plain stacked list. */
.hwd-mobile-body .hwd-menu {
  display: block;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-mobile-body .hwd-menu > li {
  display: block;
  border-block-end: 1px solid var(--hwd-border);
}

.hwd-mobile-body .hwd-menu > li > a,
.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub {
  display: flex;
  align-items: center;
  /* No gap: the icon column owns the spacing, so component items (icon and
     label as siblings) and heading items (label nested in a span, where a gap
     applies to nothing) end up identical. */
  gap: 0;
  width: 100%;
  min-height: 44px;
  padding-block: 12px;
  padding-inline: 0;
  color: var(--hwd-heading);
  font-weight: 500;
}

/*
 * A vertical list needs a real icon column: a fixed width means every label
 * starts on the same x regardless of how wide the glyph is or how the item type
 * nests it.
 */
.hwd-mobile-body .hwd-menu > li > a > .hwd-menu-icon,
.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub .hwd-menu-icon {
  width: 24px;
  margin-inline-end: 12px;
}

.hwd-mobile-body .hwd-menu > li > a:hover { color: var(--hwd-accent-text); }

/*
 * Inside the panel the menu is an accordion: every submenu starts collapsed and
 * opens only from its own disclosure button. The desktop rules position the
 * submenu absolutely and lay it out in columns, so all of that is unwound here.
 */
.hwd-mobile-body .hwd-dropdown,
.hwd-mobile-body .hwd-has-dropdown[data-hwd-open] > .hwd-dropdown {
  position: static;
  width: auto;
  min-width: 0;
  /*
   * The desktop submenu is a scroll container: it is capped at 70vh and scrolls
   * inside itself. In the panel it must be neither, or it becomes a second
   * scroller nested in the one that matters - and because its height is no
   * longer capped, that inner scroller has nothing to scroll while
   * `overscroll-behavior: contain` stops the gesture reaching the panel behind
   * it. The result is a menu that simply refuses to move under your finger.
   */
  max-height: none;
  overflow: visible;
  overscroll-behavior: auto;
  margin-inline: 0;
  padding: 0 0 12px;
  border: 0;
  border-radius: 0;
  background: none;
  backdrop-filter: none;
  box-shadow: none;
  transform: none;
  grid-template-columns: minmax(0, 1fr);
}

.hwd-mobile-body .hwd-has-dropdown > .hwd-dropdown { display: none; }
.hwd-mobile-body .hwd-has-dropdown[data-hwd-open] > .hwd-dropdown { display: block; }

/* Nested submenus indent instead of flying out sideways. */
.hwd-mobile-body .hwd-dropdown .hwd-dropdown {
  inset-inline-start: auto;
  inset-block-start: auto;
  padding-inline-start: 14px;
}

/* The disclosure control becomes the row itself. */
.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub,
.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub:not(:has(.mod-menu__heading, .mod-menu__separator)),
.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub:has(.mod-menu__heading, .mod-menu__separator) {
  position: static;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  height: auto;
  padding: 12px 0;
  transform: none;
  font: inherit;
  color: var(--hwd-heading);
  text-align: start;
}

.hwd-mobile-body .hwd-menu > li > .mod-menu__toggle-sub .hwd-caret {
  position: static;
  inset-inline-end: auto;
  width: 14px;
  height: 14px;
}

/*
 * A parent row has one of two shapes: either the disclosure button *is* the row
 * (heading and separator parents), or the row is a link with the disclosure
 * beside it. A two-column grid handles both without the button wrapping onto a
 * second line, which is what a flex row did.
 */
.hwd-mobile-body .hwd-menu > .hwd-has-dropdown {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
}

.hwd-mobile-body .hwd-menu > .hwd-has-dropdown > a {
  grid-column: 1;
  padding-inline-end: 0;
}

/* The button is the whole row... */
.hwd-mobile-body .hwd-menu > .hwd-has-dropdown > .mod-menu__toggle-sub {
  grid-column: 1 / -1;
}

/* ...unless the item has its own link, in which case it is just the chevron. */
.hwd-mobile-body .hwd-menu > .hwd-has-dropdown > a + .mod-menu__toggle-sub {
  grid-column: 2;
  justify-content: center;
  width: 44px;
  min-width: 44px;
  margin-inline: 0;
  padding-inline: 0;
}

.hwd-mobile-body .hwd-menu > .hwd-has-dropdown > .hwd-dropdown { grid-column: 1 / -1; }

/* Submenu rows inside the panel are plain list rows, not media cards. */
.hwd-mobile-body .hwd-menu > li > .hwd-dropdown > li > a {
  align-items: center;
  gap: 10px;
  padding: 10px 0;
}

.hwd-mobile-body .hwd-menu > li > .hwd-dropdown > li > a > img,
.hwd-mobile-body .hwd-menu > li > .hwd-dropdown > li > a > .fas,
.hwd-mobile-body .hwd-menu > li > .hwd-dropdown > li > a > .far,
.hwd-mobile-body .hwd-menu > li > .hwd-dropdown > li > a > .fab {
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  font-size: 1.125rem;
}

.hwd-mobile-body .hwd-menu-subtext { display: none; }

/* -- Buttons ----------------------------------------------- */
.hwd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 14px 28px;
  border: 0;
  border-radius: var(--hwd-radius-pill);
  font-weight: 600;
  font-size: .875rem;
  letter-spacing: .02em;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--hwd-transition), box-shadow var(--hwd-transition), background var(--hwd-transition), color var(--hwd-transition);
}

.hwd-btn-primary {
  background: var(--hwd-primary-gradient);
  color: var(--hwd-on-accent);
  box-shadow: var(--hwd-shadow-brand);
}

.hwd-btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: var(--hwd-shadow-brand-hover);
  color: var(--hwd-on-accent);
}

.hwd-btn-dark {
  background: var(--hwd-dark);
  color: var(--hwd-contrast-head);
  box-shadow: var(--hwd-shadow);
}

.hwd-btn-dark:hover {
  transform: translateY(-1px);
  background: var(--hwd-secondary);
  color: var(--hwd-contrast-head);
  box-shadow: var(--hwd-shadow-lg);
}

.hwd-btn-light {
  border: 1px solid var(--hwd-border);
  background: var(--hwd-surface);
  color: var(--hwd-heading);
}

.hwd-btn-light:hover {
  background: var(--hwd-surface-2);
  color: var(--hwd-heading);
}

/* -- Call to action (footer-cta position) -------------------- */
/* A plain block on whatever surface the section has: heading, one line of
   copy, one button. No band of its own. */
.hwd-cta .hwd-container { padding-inline: 0; }
.hwd-cta h2 { margin-block-end: 8px; }

.hwd-cta-sub {
  max-width: 60ch;
  margin: 0 0 22px;
  color: var(--hwd-text);
}

/* -- Brand block in module content --------------------------- */
/* The logo in the footer address block: sized by height, with width/height
   attributes on the <img> so the block never shifts while it loads. */
.hwd-brand-logo {
  display: block;
  width: auto;
  height: 32px;
  margin-block-end: 6px;
}

/* -- Hero -------------------------------------------------- */
.hwd-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 580px;
  padding-block: 70px;
  overflow: hidden;
  /* The page colour itself, flat: no gradient, no tint. --hwd-surface is not
     usable here - an ancestor re-maps it to a raised, primary-tinted surface -
     so the hero takes the neutral token, which follows the theme on its own. */
  background: var(--hwd-n0);
  text-align: center;
}

.hwd-hero-track {
  position: relative;
  z-index: 1;
  width: 100%;
}

.hwd-hero-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-inline: 20px;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--hwd-transition-fade);
}

.hwd-hero-slide.is-active {
  position: relative;
  opacity: 1;
  visibility: visible;
}

.hwd-hero-overlay {
  max-width: 960px;
  margin-inline: auto;
  text-align: center;
}

.hwd-hero-overlay h1 {
  margin: 0 0 18px;
  color: var(--hwd-heading);
  font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -.02em;
}

.hwd-hero-overlay p {
  max-width: 640px;
  margin: 0 auto 28px;
  color: var(--hwd-text);
  font-size: clamp(1rem, 2vw, 1.125rem);
  line-height: 1.6;
}

.hwd-hero-prev,
.hwd-hero-next {
  position: absolute;
  inset-block-start: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--hwd-border);
  border-radius: 50%;
  background: var(--hwd-surface);
  color: var(--hwd-heading);
  box-shadow: var(--hwd-shadow-sm);
  transform: translateY(-50%);
  cursor: pointer;
}

.hwd-hero-prev { inset-inline-start: 24px; }
.hwd-hero-next { inset-inline-end: 24px; }

.hwd-hero-prev:hover,
.hwd-hero-next:hover {
  background: var(--hwd-primary);
  border-color: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

.hwd-hero-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-block-start: 28px;
}

.hwd-hero-dots button {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--hwd-border);
  cursor: pointer;
  transition: width var(--hwd-transition), background var(--hwd-transition);
}

.hwd-hero-dots button.is-active {
  width: 22px;
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-primary);
}

/* Slider pause control - WCAG 2.2 SC 2.2.2 requires a way to stop motion. */
.hwd-slider-pause {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-inline-start: 8px;
  padding: 0;
  border: 1px solid var(--hwd-border);
  border-radius: 50%;
  background: var(--hwd-surface);
  color: var(--hwd-heading);
  font-size: .6875rem;
  cursor: pointer;
}

.hwd-slider-pause:hover {
  background: var(--hwd-primary);
  border-color: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

/* -- Hero icon row ----------------------------------------- */
.hwd-hero-icons {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 28px;
  margin-block-start: 48px;
}

.hwd-hero-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 132px;
  color: var(--hwd-heading);
  font-size: .8125rem;
  font-weight: 500;
  text-align: center;
  transition: color var(--hwd-transition);
}

/*
 * The mark is a glyph, not a tile: no plate, no frame, no shadow.
 *
 * Being text is the point. A glyph takes `color`, so it inherits the heading
 * token and is dark on the light page and near-white on the dark one without a
 * single theme rule - which a flat SVG file, the previous approach, can never
 * do. An <img> still works here and gets the same bare treatment.
 */
.hwd-hero-icon [class*="fa-"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The box is reserved at the glyph's own size, so the row does not jump when
     the lazily-loaded icon font finally arrives. */
  min-width: var(--hwd-hero-icon-size);
  min-height: var(--hwd-hero-icon-size);
  font-size: var(--hwd-hero-icon-size);
  line-height: 1;
  color: inherit;
  transition: transform var(--hwd-transition-slow);
}

.hwd-hero-icon img {
  width: 44px;
  height: 44px;
  transition: transform var(--hwd-transition-slow);
}

.hwd-hero-icon:hover { color: var(--hwd-accent-text); }

.hwd-hero-icon:hover [class*="fa-"],
.hwd-hero-icon:hover img { transform: translateY(-6px); }

/* -- Services ---------------------------------------------- */
.hwd-services-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px;
}

.hwd-service {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 22px;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-lg);
  background: var(--hwd-card-bg);
  transition: transform var(--hwd-transition), box-shadow var(--hwd-transition);
}

.hwd-service:hover {
  transform: translateY(-2px);
  box-shadow: var(--hwd-shadow);
}

.hwd-service-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: var(--hwd-radius);
  background: var(--hwd-primary-tint);
  color: var(--hwd-accent-text);
  font-size: 1.25rem;
}

.hwd-service h3 {
  margin: 0 0 6px;
  font-size: 1rem;
}

.hwd-service p {
  margin: 0;
  color: var(--hwd-text);
  font-size: .8125rem;
  line-height: 1.5;
}

/* -- Clients ----------------------------------------------- */
.hwd-clients {
  padding-block: 40px;
  border-block: 1px solid var(--hwd-border);
  background: var(--hwd-card-bg);
}

.hwd-clients-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: center;
  gap: 24px;
}

/* The logos keep their own colours in both themes; only the resting opacity
   differs, and dark.css lifts it so they stay legible on a dark ground. */
.hwd-clients-grid img {
  width: 100%;
  max-width: 110px;
  margin-inline: auto;
  filter: grayscale(100%);
  opacity: .65;
  transition: filter var(--hwd-transition), opacity var(--hwd-transition);
}

.hwd-clients-grid img:hover {
  filter: none;
  opacity: 1;
}

/* -- Language switcher ------------------------------------- */
.hwd-lang { display: flex; }

.hwd-lang-svg {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-lang-svg.hwd-lang-block {
  flex-direction: column;
  align-items: flex-start;
}

.hwd-lang-svg li { list-style: none; }

.hwd-lang-svg a {
  display: inline-flex;
  padding: 2px;
  border-radius: 5px;
  transition: opacity var(--hwd-transition), transform var(--hwd-transition);
}

.hwd-lang-svg svg {
  display: block;
  width: 20px;
  height: 14px;
  border-radius: 3px;
  outline: 1px solid color-mix(in srgb, var(--hwd-ink-strong) 15%, transparent);
  outline-offset: -1px;
}

.hwd-lang-svg li:not(.lang-active) a { opacity: .55; }

.hwd-lang-svg li:not(.lang-active) a:hover,
.hwd-lang-svg li:not(.lang-active) a:focus-visible {
  opacity: 1;
  transform: translateY(-1px);
}

.hwd-lang-svg li.lang-active a {
  opacity: 1;
  outline: 2px solid var(--hwd-primary);
  outline-offset: 1px;
}

.hwd-lang-code {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 14px;
  padding-inline: 3px;
  border-radius: 3px;
  background: var(--hwd-surface-2);
  color: var(--hwd-heading);
  font-size: .5625rem;
  font-weight: 700;
  letter-spacing: .04em;
}

/* -- Back to top ------------------------------------------- */
.hwd-backtop {
  position: fixed;
  inset-inline-end: 18px;
  inset-block-end: 18px;
  z-index: var(--hwd-z-backtop);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--hwd-border);
  border-radius: 50%;
  background: var(--hwd-surface);
  color: var(--hwd-heading);
  font-size: 1.125rem;
  box-shadow: var(--hwd-shadow-modal);
  transition: background var(--hwd-transition), color var(--hwd-transition), border-color var(--hwd-transition);
}

.hwd-backtop:hover {
  background: var(--hwd-primary);
  border-color: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

.hwd-backtop[hidden] { display: none; }

/* -- Capability block: our own PrestaShop addons ------------ */
/* Two columns: the claim on the left, the proof of breadth on the right. The
   number carries the argument, so it is given the size to do it. */
.hwd-addons {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: center;
}

.hwd-addons .hwd-addons-count {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-block-end: 6px;
  color: var(--hwd-accent-text);
  font-family: var(--hwd-font-family-display);
  font-size: clamp(3rem, 7vw, 4.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}

.hwd-addons .hwd-addons-count small {
  font-size: clamp(.9375rem, 1.6vw, 1.125rem);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--hwd-heading);
}

.hwd-addons-title {
  margin: 0 0 12px;
  font-size: var(--hwd-h2-size);
  line-height: 1.2;
}

.hwd-addons-text {
  max-width: 46ch;
  margin: 0 0 24px;
  color: var(--hwd-text);
  font-size: 1rem;
  line-height: 1.65;
}

/* The chips are the evidence: each one is a real family of addons in the
   catalogue, so breadth is shown rather than asserted. */
.hwd-addons-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-addons-tags li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-card-bg);
  color: var(--hwd-heading);
  font-size: .84375rem;
  font-weight: 500;
  line-height: 1.3;
}

.hwd-addons-tags [class*="fa-"] {
  font-size: .875rem;
  color: var(--hwd-accent-text);
}

.hwd-addons-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 22px;
  margin-block-start: 26px;
}

/* -- Platform cards (Joomla / PrestaShop) ------------------- */
/* Two cards side by side, equal height whatever the copy does. The grid does
   the equalising - `stretch` is its default - and the card is a column so the
   link can be pushed to the bottom of both. */
.hwd-os-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  align-items: stretch;
}

/* Each card is capped and pulled toward the middle, so the pair sits as a unit
   rather than stretching to the full page width. */
.hwd-os-grid > :first-child { justify-self: end; }
.hwd-os-grid > :last-child { justify-self: start; }

.hwd-os-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 520px;
  /* The grid stretches the row; this is what makes the card fill it, which is
     the whole equal-height mechanism. */
  height: 100%;
  padding: 30px;
  border-radius: var(--hwd-radius-lg);
}

/* The neutral card reads its surface from the band it is in, so it is correct
   on any surface role and in either theme without a second rule. */
.hwd-os-card--plain {
  border: 1px solid var(--hwd-border);
  background: var(--hwd-card-bg);
  color: var(--hwd-text);
}

/* The brand card carries its own pair: --hwd-on-accent is computed to be
   readable on --hwd-primary, and neither of them flips with the theme. */
.hwd-os-card--brand {
  border: 1px solid var(--hwd-primary);
  background: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

.hwd-os-logo {
  float: inline-start;
  width: 180px;
  height: 180px;
  margin-inline-end: 18px;
  margin-block-end: 8px;
  shape-outside: margin-box;
}

/* A float escapes a flex column, so the block that clears it has to be the one
   the text lives in - hence the body wrapper rather than a gap. */
.hwd-os-body { min-width: 0; }
.hwd-os-body > * { margin: 0 0 12px; }
.hwd-os-body > :last-child { margin-block-end: 0; }

/* `.hwd-band h3 { color: inherit }` sits at the same weight as an element
   selector would, so the title needs a class to state its own colour. */
.hwd-os-card .hwd-os-title {
  margin: 0;
  font-size: var(--hwd-h3-size);
  font-weight: 700;
  line-height: 1.3;
}

.hwd-os-card--plain .hwd-os-title { color: var(--hwd-heading); }
.hwd-os-card--brand .hwd-os-title { color: var(--hwd-on-accent); }

.hwd-os-card p {
  margin: 0;
  font-size: .90625rem;
  line-height: 1.7;
  color: inherit;
}

/* Pushed to the bottom, so both cards end on their link at the same line. */
.hwd-os-card .hwd-os-more {
  display: block;
  clear: both;
  margin-block-start: auto;
  padding-block-start: 10px;
  font-weight: 600;
  color: inherit;
}

.hwd-os-card--plain .hwd-os-more { color: var(--hwd-link); }

/* ============================================================
   6. JOOMLA COMPONENT VIEWS
   ============================================================ */

/* Cassiopeia's own header container is not used by this template. */
.container-header { display: none; }

/* mod_homeblocks sizes its row titles itself (30-40px). The template owns the
   type scale, and its stylesheet loads after the module's, so the same
   selector restated here puts those titles on the site's h2 step. */
.hwd-homeblocks .hwd-feature-row__content h2 { font-size: var(--hwd-h2-size); }

/* -- Cards / messages -------------------------------------- */
.card {
  overflow: hidden;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius);
  background: var(--hwd-card-bg);
}

.card-header {
  background: var(--hwd-surface-2);
  color: var(--hwd-heading);
  font-weight: 600;
  border-block-end-color: var(--hwd-border);
}

/* joomla-alert hard-codes a white background at #id specificity, which is
   invisible ink on the dark page; it is restated here on the surface token so
   it follows the theme. Matching the selector is what wins the cascade. */
#system-message-container joomla-alert {
  background-color: var(--hwd-surface);
  color: var(--hwd-text);
}

/* Unpublished-item marker in blog lists, on the theme's own tokens. */
.system-unpublished {
  background: color-mix(in srgb, var(--hwd-ink) 4%, transparent);
  border-inline-start: 3px solid var(--hwd-warning);
}

/* Bootstrap paints .form-text with a hard-coded light-theme grey which lands
   at 1.2:1 on the dark page. A field hint is an instruction, not decoration,
   so it takes the theme's own muted token. Every Joomla form on the site
   renders hints through this class, so it is not scoped to one page. */
.form-text { color: var(--hwd-muted); }

/* Pagination. Bootstrap lays this out as a non-wrapping flex row, which is
   what pushes narrow screens sideways on long result sets. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: center;
}

.pagination .page-link {
  min-width: 40px;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.pagination__wrapper,
.hwd-blog-pagination,
.hwd-sc-pagination { max-width: 100%; }

/* Optional module subtitle, printed by a module layout directly beneath the
   title that the module chrome emits. Sized between the heading and body copy
   so it reads as a deck, not as a second heading. */
.hwd-module-subtitle {
  max-width: 68ch;
  margin: -.25em 0 1.25em;
  color: var(--hwd-muted);
  font-size: clamp(1rem, 1.6vw, 1.125rem);
  line-height: 1.55;
}

/* When the title block is centred or end-aligned, the measure has to move with
   it - otherwise the text centres inside a box still hugging the start edge. */
.hwd-module-subtitle.text-center { margin-inline: auto; }
.hwd-module-subtitle.text-end { margin-inline: auto 0; }
.hwd-section-head .hwd-module-subtitle {
  margin-inline: auto;
  text-align: center;
}

/* Article info list rendered by joomla.content.info_block. */
.article-info dd {
  float: inline-start;
  margin-inline-end: 10px;
  padding: 0;
}

/* -- Category blog (html/com_content/category/blog.php) ----- */
.hwd-blog { min-width: 0; }

.hwd-blog-header { margin-block-end: 2rem; }

.hwd-blog-header h1,
.hwd-blog-header h2 {
  margin: 0 0 .5rem;
  font-size: var(--hwd-h1-size);
  font-weight: 800;
  letter-spacing: -.02em;
}

.hwd-blog-header .category-desc {
  max-width: 720px;
  color: var(--hwd-text);
}

.hwd-blog-empty {
  padding: 1.25rem;
  border-radius: var(--hwd-radius);
  background: var(--hwd-surface-2);
  color: var(--hwd-text);
}

.hwd-blog-leading,
.hwd-blog-grid {
  display: grid;
  gap: var(--hwd-gap);
  margin-block-end: var(--hwd-gap);
}

.hwd-blog-grid.columns-2,
.hwd-blog-grid.masonry-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hwd-blog-grid.columns-3,
.hwd-blog-grid.masonry-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hwd-blog-grid.columns-4,
.hwd-blog-grid.masonry-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.hwd-blog-grid__item {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-lg);
  background: var(--hwd-card-bg);
  transition: transform var(--hwd-transition), box-shadow var(--hwd-transition);
}

.hwd-blog-grid__item:hover {
  transform: translateY(-3px);
  box-shadow: var(--hwd-shadow);
}

.hwd-blog-grid__item > figure,
.hwd-blog-grid__item .item-image {
  margin: 0;
  overflow: hidden;
}

.hwd-blog-grid__item img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.hwd-blog-grid__item .item-content {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 1.25rem;
}

.hwd-blog-grid__item .page-header,
.hwd-blog-grid__item h2,
.hwd-blog-grid__item h3 {
  margin: 0 0 .5rem;
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
}

.hwd-blog-grid__item .readmore { margin-block-start: auto; }

.hwd-blog-more,
.hwd-blog-children,
.hwd-blog-pagination { margin-block: var(--hwd-gap); }

.hwd-blog-children h2 {
  margin: 0 0 .75rem;
  font-size: var(--hwd-h4-size);
  font-weight: 700;
}

/* -- Category showcase (html/com_content/category/showcase.php) */
.hwd-showcase { min-width: 0; }

.hwd-sc-head {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
  margin-block-end: 2.5rem;
  padding-block-end: 2rem;
  border-block-end: 1px solid var(--hwd-separator);
}

.hwd-sc-cat-image {
  flex-shrink: 0;
  width: 120px;
  height: 120px;
  overflow: hidden;
  border-radius: var(--hwd-radius-xl);
}

.hwd-sc-cat-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hwd-sc-head-text {
  flex: 1;
  min-width: 0;
}

.hwd-sc-head-text h1,
.hwd-sc-head-text h2,
.hwd-sc-title {
  margin: 0 0 .5rem;
  color: var(--hwd-heading);
  font-size: var(--hwd-h1-size);
  font-weight: 800;
  letter-spacing: -.02em;
}

/* The article count rides on the title like an exponent: a filled circle, the
   number and nothing else. The word it used to carry is kept for screen
   readers, where a lone digit beside a heading would mean nothing. */
.hwd-sc-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9em;
  height: 1.9em;
  margin-inline-start: .5em;
  padding-inline: .45em;
  border-radius: var(--hwd-radius-pill);
  /* The brand colour, not the accent: --hwd-accent-text is lightened for the
     dark theme so it can be read *as text on the page*, and white on top of
     that lightened blue only reaches 2.4:1. --hwd-on-accent is computed to be
     readable on --hwd-primary, so this pair is correct in both themes by
     construction. */
  background: var(--hwd-primary);
  color: var(--hwd-on-accent);
  /* Sized against the heading, so it stays proportional as the title scales. */
  font-size: .34em;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  vertical-align: super;
}

.hwd-sc-desc {
  margin-block-start: 14px;
  color: var(--hwd-text);
  font-size: .95rem;
  line-height: 1.7;
}

.hwd-sc-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem;
  /* Rendered as a <p>: reset the Bootstrap paragraph margin. */
  margin: 0;
  color: var(--hwd-muted);
  font-size: .8rem;
}

.hwd-sc-chip {
  display: inline-block;
  padding: .2rem .65rem;
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-primary);
  color: var(--hwd-btn-text);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .3px;
  text-transform: uppercase;
}

/* Hero card: image on one side, copy on the other. */
.hwd-sc-hero {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  min-height: 400px;
  margin-block-end: 2.5rem;
  overflow: hidden;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-xl);
  background: var(--hwd-card-bg);
}

.hwd-sc-hero--text { grid-template-columns: minmax(0, 1fr); }

.hwd-sc-hero-media {
  position: relative;
  min-height: 400px;
  overflow: hidden;
}

.hwd-sc-hero-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hwd-sc-hero-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 760px;
  padding: 2.5rem;
}

.hwd-sc-hero-body h2 {
  margin: .75rem 0;
  color: var(--hwd-heading);
  font-size: clamp(1.25rem, 1.05rem + .9vw, 1.5rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -.015em;
}

.hwd-sc-hero-body h2 a { color: inherit; }
.hwd-sc-hero-body h2 a:hover { color: var(--hwd-accent-text); }

.hwd-sc-hero-body p {
  margin: 0 0 1.5rem;
  color: var(--hwd-text);
  font-size: .95rem;
  line-height: 1.7;
}

/* Card grid */
.hwd-sc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 1.5rem;
  margin-block-end: 2.5rem;
}

.hwd-sc-grid--1col { grid-template-columns: minmax(0, 1fr); }
.hwd-sc-grid--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hwd-sc-grid--3col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hwd-sc-grid--4col { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.hwd-sc-card-item {
  display: flex;
  min-width: 0;
}

.hwd-sc-card {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-xl);
  background: var(--hwd-card-bg);
  transition: transform var(--hwd-transition-mid), box-shadow var(--hwd-transition-mid), border-color var(--hwd-transition-mid);
}

.hwd-sc-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--hwd-shadow);
}

.hwd-sc-card-media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  overflow: hidden;
}

.hwd-sc-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--hwd-transition-fade);
}

.hwd-sc-card:hover .hwd-sc-card-media img { transform: scale(1.04); }

.hwd-sc-card-media .hwd-sc-chip {
  position: absolute;
  inset-block-start: .75rem;
  inset-inline-start: .75rem;
}

/* Placeholder used when an article has no image, so a row of cards keeps one
   baseline instead of some starting with a picture and some with text. */
.hwd-sc-card-media--empty {
  background:
    linear-gradient(135deg, var(--hwd-surface-2) 0%, var(--hwd-surface-3) 100%);
}

.hwd-sc-card-media--empty::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 30% 30%, var(--hwd-primary-tint), transparent 60%);
}

.hwd-sc-card-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 1.25rem;
}

.hwd-sc-card-body h3 {
  margin: .5rem 0;
  color: var(--hwd-heading);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
}

.hwd-sc-card-body h3 a { color: inherit; }
.hwd-sc-card-body h3 a:hover { color: var(--hwd-accent-text); }

.hwd-sc-ex {
  margin-block-end: .75rem;
  color: var(--hwd-text);
  font-size: .85rem;
  line-height: 1.6;
}

.hwd-sc-more {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin-block-start: auto;
  color: var(--hwd-accent-text);
  font-size: .8rem;
  font-weight: 600;
}

.hwd-sc-more span { transition: transform var(--hwd-transition); }
.hwd-sc-more:hover span { transform: translateX(4px); }

/* Numbered link list */
.hwd-sc-links {
  display: flex;
  flex-direction: column;
  margin-block-end: 2rem;
  border-block-start: 1px solid var(--hwd-separator);
}

.hwd-sc-links a {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-block: .85rem;
  padding-inline: 0;
  border-block-end: 1px solid var(--hwd-separator);
  color: var(--hwd-text);
  transition: color var(--hwd-transition), background var(--hwd-transition), padding-inline-start var(--hwd-transition);
}

.hwd-sc-links a:hover {
  padding-inline-start: 14px;
  background: var(--hwd-surface-2);
  color: var(--hwd-accent-text);
}

.hwd-sc-links-num {
  min-width: 2.5rem;
  color: var(--hwd-accent-text);
  font-size: 1.4rem;
  font-weight: 800;
}

.hwd-sc-links-title {
  flex: 1;
  color: var(--hwd-heading);
  font-size: .95rem;
  font-weight: 600;
}

.hwd-sc-links-date {
  color: var(--hwd-muted);
  font-size: .8rem;
}

/* Child categories */
.hwd-sc-children { margin-block-end: 2rem; }

.hwd-sc-children h2 {
  margin: 0 0 .75rem;
  color: var(--hwd-heading);
  font-size: var(--hwd-h4-size);
  font-weight: 700;
}

.hwd-sc-children-grid {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-block-end: 36px;
}

.hwd-sc-children .hwd-sc-chip {
  padding: .4rem 1rem;
  background: var(--hwd-surface-2);
  color: var(--hwd-text);
  font-size: .85rem;
  text-transform: none;
}

.hwd-sc-children .hwd-sc-chip:hover {
  background: var(--hwd-primary);
  color: var(--hwd-btn-text);
}

.hwd-sc-empty {
  margin: 0;
  padding: 2rem;
  border-radius: var(--hwd-radius-xl);
  background: var(--hwd-surface-2);
  color: var(--hwd-muted);
  text-align: center;
}

.hwd-sc-pagination { margin-block: 2rem; }

/* -- Article "blog" layout (html/com_content/article/blog.php) */
.hwd-ab {
  max-width: 100%;
  margin: 0;
  padding: 0;
}

.hwd-ab-hero {
  width: 100%;
  max-height: 520px;
  margin-block-end: 2.5rem;
  overflow: hidden;
}

.hwd-ab-hero img {
  display: block;
  width: 100%;
  height: 100%;
  max-height: 520px;
  object-fit: cover;
}

.hwd-ab-layout {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  align-items: start;
  gap: 3rem;
  max-width: 1100px;
  margin-inline: auto;
  padding-inline: 1rem;
}

.hwd-ab-sidebar {
  position: sticky;
  inset-block-start: 100px;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.hwd-ab-cat {
  display: inline-block;
  width: fit-content;
  padding: .3rem .85rem;
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-primary);
  color: var(--hwd-btn-text);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .5px;
  text-transform: uppercase;
}

.hwd-ab-cat:hover { color: var(--hwd-btn-text); }

.hwd-ab-date {
  color: var(--hwd-muted);
  font-size: .85rem;
}

.hwd-ab-share {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.hwd-ab-share-label {
  color: var(--hwd-muted);
  font-size: .8rem;
  font-weight: 600;
}

.hwd-ab-share-icons {
  display: flex;
  gap: .5rem;
}

.hwd-ab-share-icons a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--hwd-surface-2);
  color: var(--hwd-text);
  transition: background var(--hwd-transition), color var(--hwd-transition);
}

.hwd-ab-share-icons a:hover {
  background: var(--hwd-primary);
  color: var(--hwd-btn-text);
}

.hwd-ab-body { min-width: 0; }

.hwd-ab-title {
  margin: 0 0 2rem;
  color: var(--hwd-heading);
  font-size: var(--hwd-h1-size);
  font-weight: 800;
  line-height: 1.2;
}

.hwd-ab-edit { margin-block-end: 1rem; }

.hwd-ab-badge {
  display: inline-block;
  margin-block-end: 1rem;
  padding: .25rem .75rem;
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-warning);
  color: var(--hwd-on-accent);
  font-size: .75rem;
  font-weight: 600;
}

/* Long-form typography shared by the article body. */
.hwd-ab-content {
  color: var(--hwd-text);
  font-size: 1.05rem;
  line-height: 1.85;
}

.hwd-ab-content h2 {
  margin: 2.5rem 0 1rem;
  font-size: var(--hwd-h2-size);
  font-weight: 700;
}

.hwd-ab-content h3 {
  margin: 2rem 0 .75rem;
  font-size: var(--hwd-h3-size);
  font-weight: 600;
}

.hwd-ab-content p { margin-block-end: 1.25rem; }

.hwd-ab-content img {
  max-width: 100%;
  height: auto;
  border-radius: var(--hwd-radius);
}

.hwd-ab-content blockquote {
  margin: 1.5rem 0;
  padding: 1rem 1.5rem;
  border-inline-start: 4px solid var(--hwd-primary);
  border-start-end-radius: var(--hwd-radius);
  border-end-end-radius: var(--hwd-radius);
  background: var(--hwd-surface-2);
  font-style: italic;
}

.hwd-ab-content a {
  color: var(--hwd-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.hwd-ab-content ul,
.hwd-ab-content ol {
  margin-block: 1rem 1.25rem;
  margin-inline-start: 1.5rem;
  padding: 0;
}

.hwd-ab-content li { margin-block-end: .4rem; }

.hwd-ab-content pre {
  margin: 1.5rem 0;
  padding: 1.25rem;
  overflow-x: auto;
  border-radius: var(--hwd-radius);
  background: var(--hwd-surface-3);
  color: var(--hwd-text);
  font-size: .9rem;
  line-height: 1.6;
}

.hwd-ab-content code {
  padding: .15em .4em;
  border-radius: 4px;
  background: var(--hwd-surface-3);
  font-size: .9em;
}

.hwd-ab-content pre code {
  padding: 0;
  background: none;
}

.hwd-ab-content table {
  width: 100%;
  border-collapse: collapse;
}

.hwd-ab-content th,
.hwd-ab-content td {
  padding: .5rem .75rem;
  border: 1px solid var(--hwd-border);
  text-align: start;
}

.hwd-ab-tags {
  margin-block: 2rem;
  padding-block-start: 1.5rem;
  border-block-start: 1px solid var(--hwd-separator);
}

.hwd-ab-tags .tags a,
.hwd-ab-tags .tag-name {
  display: inline-block;
  padding: .35rem .85rem;
  border-radius: var(--hwd-radius-pill);
  background: var(--hwd-surface-2);
  color: var(--hwd-text);
  font-size: .8rem;
  font-weight: 500;
  transition: background var(--hwd-transition), color var(--hwd-transition);
}

.hwd-ab-tags .tags a:hover {
  background: var(--hwd-primary);
  color: var(--hwd-btn-text);
}

.hwd-ab-pagination {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-block-end: 2rem;
  padding-block-start: 1.5rem;
  border-block-start: 1px solid var(--hwd-separator);
}

.hwd-ab-pagination a {
  color: var(--hwd-link);
  font-weight: 600;
}

/* -- Client portfolio (article layout: portfolio) ----------- */
.hwd-pf-heading { margin-block-end: .35em; }

.hwd-pf-intro,
.hwd-pf-outro { max-width: 62ch; }

.hwd-pf-intro > :last-child { margin-block-end: 0; }

.hwd-pf-grid {
  display: grid;
  /* One up, two from the small breakpoint, three from the medium one - the
     same rhythm as the rest of the module grids. */
  grid-template-columns: 1fr;
  gap: var(--hwd-gap);
  margin-block: 40px 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 576px) {
  .hwd-pf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
  .hwd-pf-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.hwd-pf-item { display: flex; }

.hwd-pf-card {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-lg);
  background: var(--hwd-card-bg);
  color: var(--hwd-text);
  text-decoration: none;
  transition: transform var(--hwd-transition-slow), box-shadow var(--hwd-transition-slow),
    border-color var(--hwd-transition);
}

@media (hover: hover) and (pointer: fine) {
  a.hwd-pf-card:hover {
    transform: translateY(-4px);
    border-color: var(--hwd-primary);
    box-shadow: var(--hwd-shadow-lg);
  }
}

a.hwd-pf-card:focus-visible {
  outline: var(--hwd-focus-width) solid var(--hwd-focus);
  outline-offset: var(--hwd-focus-offset);
}

/* The screenshot. A fixed ratio is what keeps the row of cards aligned whatever
   the source images measure, and reserves the space before they load. */
.hwd-pf-media {
  display: block;
  /* Slightly taller than a browser screenshot measures, so what `cover` trims
     is a sliver off each side rather than the bottom of the frame. */
  aspect-ratio: 12 / 7;
  overflow: hidden;
  background: var(--hwd-surface-2);
  border-block-end: 1px solid var(--hwd-border);
}

.hwd-pf-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform var(--hwd-transition-slow);
}

@media (hover: hover) and (pointer: fine) {
  a.hwd-pf-card:hover .hwd-pf-media img { transform: scale(1.04); }
}

.hwd-pf-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 4px;
  padding: 18px 20px 20px;
}

.hwd-pf-title {
  display: block;
  color: var(--hwd-heading);
  font-family: var(--hwd-font-family-headings);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.3;
}

.hwd-pf-meta {
  display: block;
  color: var(--hwd-muted);
  font-size: .8125rem;
  line-height: 1.5;
}

/* The "opens elsewhere" cue. It sits in the corner of the card and only
   asserts itself on hover, so the grid stays quiet at rest. */
.hwd-pf-go {
  position: absolute;
  inset-block-start: 12px;
  inset-inline-end: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--hwd-card-bg);
  color: var(--hwd-accent-text);
  box-shadow: var(--hwd-shadow-sm);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--hwd-transition), transform var(--hwd-transition);
}

a.hwd-pf-card:hover .hwd-pf-go,
a.hwd-pf-card:focus-visible .hwd-pf-go {
  opacity: 1;
  transform: none;
}

.hwd-pf-outro { margin-block-start: 40px; }
.hwd-pf-tags { margin-block-start: 28px; }

/* -- FAQ accordion (article layout: faq) -------------------- */
.hwd-faq-heading { margin-block-end: .4em; }

.hwd-faq-intro,
.hwd-faq-outro { max-width: 68ch; }

.hwd-faq-intro > :last-child { margin-block-end: 0; }

.hwd-faq-list {
  display: grid;
  gap: 12px;
  margin-block-start: 36px;
}

/* No fill of its own: whatever surface role the section is given owns the
   background, and the accordion sits on it. Only the outline and the open
   state are drawn here, because those carry meaning rather than colour. */
.hwd-faq-item {
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius);
  background: transparent;
  overflow: hidden;
  transition: border-color var(--hwd-transition), box-shadow var(--hwd-transition);
}

.hwd-faq-item[open] { border-color: var(--hwd-primary); }

/* The question is the disclosure control. Removing the native marker and
   drawing our own is the only reason ::marker and ::-webkit-details-marker
   appear here; the element keeps all of its built-in behaviour. */
.hwd-faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 20px;
  color: var(--hwd-heading);
  font-family: var(--hwd-font-family-headings);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.45;
  list-style: none;
  cursor: pointer;
  transition: color var(--hwd-transition);
}

.hwd-faq-q::-webkit-details-marker { display: none; }
.hwd-faq-q::marker { content: ""; }

@media (hover: hover) and (pointer: fine) {
  .hwd-faq-q:hover { color: var(--hwd-accent-text); }
}

.hwd-faq-q:focus-visible {
  outline: var(--hwd-focus-width) solid var(--hwd-focus);
  outline-offset: -2px;
  border-radius: var(--hwd-radius);
}

/* A plus that becomes a minus: two bars, one of which rotates away. */
.hwd-faq-mark {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: var(--hwd-radius-pill);
  color: var(--hwd-accent-text);
}

.hwd-faq-mark::before,
.hwd-faq-mark::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: 13px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--hwd-transition-slow), opacity var(--hwd-transition);
}

.hwd-faq-mark::after { transform: translate(-50%, -50%) rotate(90deg); }

.hwd-faq-item[open] .hwd-faq-mark::after {
  transform: translate(-50%, -50%) rotate(0deg);
  opacity: 0;
}

.hwd-faq-a {
  padding: 0 20px 20px;
  color: var(--hwd-text);
  font-size: .9375rem;
  line-height: 1.7;
}

.hwd-faq-a > :first-child { margin-block-start: 0; }
.hwd-faq-a > :last-child { margin-block-end: 0; }
.hwd-faq-a a { color: var(--hwd-link); }

/* Browsers that support it animate the panel open; the rest simply snap, which
   is the correct fallback rather than a scripted height calculation. */
@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    .hwd-faq-item {
      interpolate-size: allow-keywords;
    }

    .hwd-faq-item::details-content {
      block-size: 0;
      overflow: hidden;
      transition: block-size var(--hwd-transition-slow), content-visibility var(--hwd-transition-slow);
      transition-behavior: allow-discrete;
    }

    .hwd-faq-item[open]::details-content { block-size: auto; }
  }
}

/* Two columns where there is room for them. The items are independent
   disclosures, so a column split costs nothing in meaning - unlike a table,
   nothing here is read across the rows. */
.hwd-faq-list--2col { margin-block-start: 28px; }

@media (min-width: 992px) {
  .hwd-faq-list--2col {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 14px 24px;
  }
}

.hwd-faq-outro { margin-block-start: 36px; }
.hwd-faq-tags { margin-block-start: 28px; }

/* -- Breadcrumb trail -------------------------------------- */
/* It sits at the foot of the article, so it opens with a rule that closes the
   text above it rather than a label that interrupts it. */
.hwd-crumbs {
  margin-block-start: 48px;
  padding-block-start: 20px;
  border-block-start: 1px solid var(--hwd-border);
}

.hwd-crumbs-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 0;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: .8125rem;
  line-height: 1.5;
}

.hwd-crumb {
  display: inline-flex;
  align-items: center;
  color: var(--hwd-muted);
}

/* The separator is drawn, not typed: a chevron on the ::before of every item
   after the first needs no markup and never ends up read out as text. */
.hwd-crumb + .hwd-crumb::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin-inline: 12px;
  border-inline-end: 1.5px solid currentColor;
  border-block-start: 1.5px solid currentColor;
  transform: rotate(45deg);
  opacity: .5;
}

[dir="rtl"] .hwd-crumb + .hwd-crumb::before { transform: rotate(-135deg); }

.hwd-crumb-link {
  padding-block: 4px;
  color: var(--hwd-muted);
  text-decoration: none;
  border-block-end: 1px solid transparent;
  transition: color var(--hwd-transition), border-color var(--hwd-transition);
}

@media (hover: hover) and (pointer: fine) {
  .hwd-crumb-link:hover {
    color: var(--hwd-link);
    border-block-end-color: currentColor;
  }
}

.hwd-crumb-link:focus-visible {
  outline: var(--hwd-focus-width) solid var(--hwd-focus);
  outline-offset: 3px;
  border-radius: 3px;
}

/* The page you are on carries the weight; the path to it stays quiet. */
.hwd-crumb-current {
  color: var(--hwd-heading);
  font-weight: 500;
}

/* -- Contact page (html/com_contact/contact) ---------------- */
/* The page has one job: collect a usable enquiry. The form owns the wide
   column; the studio's own details sit beside it as a card that stays in view
   while the form is filled. On narrow screens the card comes first - someone
   reaching for a phone number should not have to scroll a form to find it.

   The one loud element is the service picker: eight checkboxes read as
   paperwork, so they are drawn as chips. The native input stays in the DOM,
   focusable and announced; only its appearance moves to the label, so keyboard
   and screen-reader behaviour is unchanged. */
.hwd-contact-head {
  max-width: 46rem;
  margin-block-end: 40px;
}

.hwd-contact-title { margin: 0 0 12px; }

.hwd-contact-lede {
  margin: 0;
  color: var(--hwd-muted);
  font-size: 1.0625rem;
  line-height: 1.6;
}

.hwd-contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 21rem;
  align-items: start;
  gap: 40px;
}

.hwd-contact-page--single .hwd-contact-layout {
  grid-template-columns: minmax(0, 1fr);
}

/* Details card. A light theme separates the card from the page with its
   border; a dark one cannot - a hairline on near-black reads as nothing - so
   there the surface itself lifts one step. */
.hwd-contact-card {
  position: sticky;
  inset-block-start: calc(var(--hwd-header-min-height) + 20px);
  padding: 24px;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-lg);
  background: var(--hwd-contact-surface, var(--hwd-card-bg));
}

@supports (color: light-dark(#000, #fff)) {
  .hwd-contact-page { --hwd-contact-surface: light-dark(var(--hwd-card-bg), var(--hwd-n1)); }
}

.hwd-contact-card__title {
  margin: 0 0 18px;
  font-size: 1rem;
  letter-spacing: .01em;
}

.hwd-contact-rows {
  display: grid;
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-contact-row {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: 14px;
  align-items: start;
}

.hwd-contact-row__icon {
  margin-block-start: .15em;
  color: var(--hwd-primary);
  font-size: 1.0625rem;
}

.hwd-contact-row__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.hwd-contact-row__label {
  color: var(--hwd-muted);
  font-size: .8125rem;
}

.hwd-contact-row__value {
  color: var(--hwd-heading);
  font-weight: 500;
  overflow-wrap: anywhere;
}

a.hwd-contact-row__value { text-decoration: none; }

a.hwd-contact-row__value:hover,
a.hwd-contact-row__value:focus-visible {
  color: var(--hwd-primary);
  text-decoration: underline;
}

/* The form */
.hwd-contact-form .hwd-form-step {
  margin: 0 0 36px;
  padding: 0;
  border: 0;
}

.hwd-contact-form .hwd-form-step__title {
  width: 100%;
  margin: 0 0 20px;
  padding-block-end: 10px;
  border-block-end: 1px solid var(--hwd-border);
  color: var(--hwd-heading);
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.hwd-contact-form .control-group + .control-group,
.hwd-contact-form .hwd-field + .control-group,
.hwd-contact-form .control-group + .hwd-field {
  margin-block-start: 18px;
}

.hwd-contact-form .control-label label {
  display: inline-block;
  margin-block-end: 6px;
  color: var(--hwd-heading);
  font-size: .9375rem;
  font-weight: 500;
}

.hwd-contact-form .control-label .star { color: var(--hwd-primary); }

.hwd-contact-form :is(input[type="text"], input[type="email"], input[type="tel"], input[type="url"], select, textarea) {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--hwd-input-border);
  border-radius: var(--hwd-radius);
  background: var(--hwd-contact-surface, var(--hwd-input-bg));
  color: var(--hwd-input-text);
  font: inherit;
  transition: border-color var(--hwd-transition), box-shadow var(--hwd-transition);
}

.hwd-contact-form :is(input, select, textarea):focus-visible {
  border-color: var(--hwd-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--hwd-primary) 18%, transparent);
  outline: 2px solid transparent;
  outline-offset: 0;
}

.hwd-contact-form textarea {
  min-height: 9rem;
  resize: vertical;
}

.hwd-contact-form .form-control-feedback,
.hwd-contact-form [id$="-desc"] {
  margin-block-start: 6px;
  color: var(--hwd-muted);
  font-size: .8125rem;
}

/* Bootstrap shrinks .form-text again inside the description wrapper, landing at
   about 11px. Hints inherit the size set for descriptions instead. */
.hwd-contact-form .form-text { font-size: inherit; }

/* Service picker: the one loud element */
.hwd-field--chips .control-label label { margin-block-end: 10px; }

.hwd-field--chips fieldset {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0;
  border: 0;
}

.hwd-field--chips .form-check {
  position: relative;
  margin: 0;
  padding: 0;
}

.hwd-field--chips .form-check-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.hwd-field--chips .form-check-label {
  display: block;
  padding: 9px 16px;
  border: 1px solid var(--hwd-border);
  border-radius: var(--hwd-radius-pill);
  color: var(--hwd-text);
  font-size: .9375rem;
  line-height: 1.2;
  cursor: pointer;
  user-select: none;
  transition: border-color var(--hwd-transition), background var(--hwd-transition), color var(--hwd-transition);
}

.hwd-field--chips .form-check-label:hover {
  border-color: var(--hwd-primary);
  color: var(--hwd-primary);
}

.hwd-field--chips .form-check-input:checked + .form-check-label {
  border-color: var(--hwd-primary);
  background: var(--hwd-primary);
  color: var(--hwd-on-accent);
}

.hwd-field--chips .form-check-input:focus-visible + .form-check-label {
  outline: var(--hwd-focus-width) solid var(--hwd-focus);
  outline-offset: var(--hwd-focus-offset);
}

/* Yes / no */
.hwd-field--toggle fieldset {
  display: flex;
  gap: 24px;
  padding: 0;
  border: 0;
}

.hwd-field--toggle .form-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

/* Submit */
.hwd-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  padding-block-start: 8px;
}

.hwd-form-note {
  margin: 0;
  color: var(--hwd-muted);
  font-size: .8125rem;
}

/* -- Error page -------------------------------------------- */
.hwd-error-page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

.hwd-error-header {
  padding-block: 20px;
  border-block-end: 1px solid var(--hwd-border);
}

.hwd-error-header .hwd-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 15px;
  min-height: 0;
}

.hwd-error-hero {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  padding: 72px var(--hwd-gutter);
  text-align: center;
}

.hwd-error-inner { max-width: 640px; }

.hwd-error-code {
  margin: 0 0 10px;
  background: var(--hwd-primary-gradient);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-size: clamp(5rem, 14vw, 8rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.03em;
}

.hwd-error-hero h1 {
  margin: 0 0 14px;
  color: var(--hwd-heading);
}

.hwd-error-msg {
  margin: 0 0 32px;
  color: var(--hwd-text);
  font-size: 1.0625rem;
  line-height: 1.65;
}

.hwd-error-modules { margin-block-start: 32px; }

.hwd-error-footer {
  padding-block: 20px;
  border-block-start: 1px solid var(--hwd-border);
  color: var(--hwd-muted);
  font-size: .875rem;
  text-align: center;
}

.hwd-error-debug {
  width: 100%;
  max-width: min(var(--hwd-container), 100%);
  margin-inline: auto;
  padding: 20px var(--hwd-gutter);
  font-size: .75rem;
}

/* -- Icon webfont binding -----------------------------------
   Every content icon on the site is drawn from the sharp family, unfilled:
   square corners, an outline rather than a solid fill. Font Awesome keeps a
   codepoint stable across its families, so re-pointing the font is enough -
   no menu item, layout override or markup changes - and it keeps the page on
   a single icon webfont instead of one per family.

   The weight is pinned rather than inherited on purpose. Font Awesome selects
   its face by font-weight, so an icon that inherits the surrounding text weight
   lands on the wrong face and renders nothing.

   Stroke weight: 400 regular, 300 light, 100 thin. Each is a separate webfont
   download, so changing it changes what the page fetches.

   Two deliberate exceptions:
   - .icon-joomla is a brand mark and exists only in the brands face.
   - Explicit Font Awesome markup (.fa-solid, .fa-light, .fa-duotone, .fa-brands
     and friends) is left alone, so anything written against Font Awesome's own
     class system still picks its own family and weight. */
[class^="icon-"]:not(.icon-joomla),
[class*=" icon-"]:not(.icon-joomla),
.hwd-menu-icon,
.fas {
  font-family: "Font Awesome 7 Sharp";
  font-weight: 400;
}

.icon-joomla { font-weight: 400; }

.fa-solid { font-weight: 900; }

/* ============================================================
   7. FOOTER
   ============================================================ */
.hwd-footer {
  position: relative;
  padding: 60px 0 40px;
}

.hwd-footer a { color: inherit; }
.hwd-footer a:hover { color: var(--hwd-heading); }

.hwd-footer h1,
.hwd-footer h2,
.hwd-footer h3,
.hwd-footer h4,
.hwd-footer h5,
.hwd-footer h6 { color: var(--hwd-heading); }

.hwd-footer h3 {
  margin: 0 0 14px;
  font-size: .9375rem;
  font-weight: 700;
}

.hwd-footer ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-footer li {
  padding-block: 6px;
  font-size: .8125rem;
}

.hwd-footer-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px;
}

.hwd-copyright {
  padding-block: 18px;
  font-size: .75rem;
}

.hwd-copyright p { margin: 0; }
.hwd-copyright a { color: inherit; }
.hwd-copyright a:hover { color: var(--hwd-heading); }

.hwd-copyright-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 16px;
  text-align: center;
}

/* ============================================================
   8. UTILITIES
   ============================================================ */

/* Wide content - tables, code, diagrams - scrolls inside its own box so it can
   never widen the page. */
.hwd-scroll-x {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.hwd-social {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hwd-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
}

.hwd-contact {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}

/* ============================================================
   9. RESPONSIVE
   Breakpoints follow the Bootstrap scale the base stylesheet uses (576, 768,
   992, 1200). The navigation collapses below 1200px: between 1100 and 1200
   the full row still fits, but only by squeezing the logo to a sliver.
   ============================================================ */
@media (max-width: 1199.98px) {
  .hwd-menu { display: none; }
  .hwd-burger { display: inline-flex; }

  /* Without script the panel can never open, so the navigation stays where it
     is and wraps under the brand instead of vanishing. The header grows to fit
     it, which on the front page means it can no longer float over the hero. */
  html.hwd-no-js .hwd-burger { display: none; }
  html.hwd-no-js .hwd-header-inner { flex-wrap: wrap; }
  html.hwd-no-js .hwd-header-nav {
    flex: 1 1 100%;
    flex-wrap: wrap;
    margin-inline-start: 0;
  }
  html.hwd-no-js .hwd-nav { width: 100%; }
  html.hwd-no-js .hwd-menu {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
  }
  html.hwd-no-js .hwd-menu > li > a,
  html.hwd-no-js .hwd-menu > li > .mod-menu__heading,
  html.hwd-no-js .hwd-menu > li > .mod-menu__separator,
  html.hwd-no-js .hwd-menu > li > .mod-menu__toggle-sub:has(.mod-menu__heading, .mod-menu__separator) {
    min-height: 44px;
    white-space: normal;
  }
  html.hwd-no-js .hwd-frontpage .hwd-header { position: relative; }
}

@media (min-width: 1200px) {
  .hwd-burger { display: none; }
  /* The off-canvas panel is a mobile affordance only. */
  .hwd-mobile-nav { display: none; }
}

@media (max-width: 991.98px) {
  .hwd-grid-main,
  body.has-sidebar-left .hwd-grid-main,
  body.has-sidebar-right .hwd-grid-main,
  body.has-sidebar-left.has-sidebar-right .hwd-grid-main { grid-template-columns: minmax(0, 1fr); }

  .hwd-col-4 { flex: 0 0 100%; max-width: 100%; }

  .hwd-clients-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hwd-footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hwd-sc-grid--3col,
  .hwd-sc-grid--4col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hwd-blog-grid.columns-3,
  .hwd-blog-grid.masonry-3,
  .hwd-blog-grid.columns-4,
  .hwd-blog-grid.masonry-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .hwd-os-logo { width: 120px; height: 120px; margin-inline-end: 14px; }

  .hwd-contact-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  /* Explicit rows rather than `order`: both are grid items, and placing them
     says what the layout is instead of nudging it. */
  .hwd-contact-aside { grid-row: 1; }
  .hwd-contact-main { grid-row: 2; }
  .hwd-contact-card { position: static; }
  .hwd-contact-rows { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
}

@media (max-width: 767.98px) {
  :root {
    --hwd-section-y: 56px;
    --hwd-band-y: 44px;
    --hwd-gap: 20px;
  }

  .hwd-header-inner { gap: 12px; }
  .hwd-header-actions { gap: 6px; }
  .hwd-logo-img { max-height: 36px; }
  .hwd-header-strip-inner { justify-content: center; }

  .hwd-module-col { grid-column: 1 / -1; }

  .hwd-hero {
    min-height: 560px;
    padding-block: 120px 60px;
  }

  .hwd-hero-prev,
  .hwd-hero-next { display: none; }

  .hwd-sc-head {
    flex-direction: column;
    gap: 1rem;
  }

  .hwd-sc-cat-image { width: 80px; height: 80px; }

  .hwd-sc-grid,
  .hwd-sc-grid--2col,
  .hwd-sc-grid--3col,
  .hwd-sc-grid--4col { grid-template-columns: minmax(0, 1fr); }

  .hwd-sc-hero { grid-template-columns: minmax(0, 1fr); }
  .hwd-sc-hero-media { min-height: 250px; }
  .hwd-sc-hero-body { padding: 1.5rem; }

  .hwd-blog-grid,
  .hwd-blog-grid.columns-2,
  .hwd-blog-grid.masonry-2,
  .hwd-blog-grid.columns-3,
  .hwd-blog-grid.masonry-3,
  .hwd-blog-grid.columns-4,
  .hwd-blog-grid.masonry-4 { grid-template-columns: minmax(0, 1fr); }

  .hwd-services-grid { grid-template-columns: minmax(0, 1fr); }

  .hwd-ab-hero,
  .hwd-ab-hero img { max-height: 320px; }

  .hwd-ab-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  .hwd-ab-sidebar {
    position: static;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    padding-block-end: 1.5rem;
    border-block-end: 1px solid var(--hwd-separator);
  }

  .hwd-ab-content { font-size: 1rem; }

  .hwd-addons {
    grid-template-columns: 1fr;
    gap: 32px;
    padding-block: 6px;
  }

  .hwd-addons-tags li { padding: 8px 13px; font-size: .8125rem; }

  .hwd-os-grid { grid-template-columns: 1fr; gap: 18px; }
  .hwd-os-grid > :first-child,
  .hwd-os-grid > :last-child { justify-self: center; }
  .hwd-os-card { padding: 24px; }
}

@media (max-width: 575.98px) {
  .hwd-footer-grid { grid-template-columns: minmax(0, 1fr); }
  .hwd-clients-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hwd-os-logo { width: 88px; height: 88px; }
  .hwd-faq-q { padding: 16px; font-size: .9375rem; }
  .hwd-faq-a { padding: 0 16px 16px; }
  .hwd-crumbs { margin-block-start: 32px; }
  .hwd-crumb + .hwd-crumb::before { margin-inline: 8px; }
}

/* ============================================================
   10. MOTION PREFERENCES
   Every transition reads a token, so zeroing the tokens is what honours the
   request; the element-level rule below catches the base stylesheet, content
   and third-party markup that do not. Hover lifts are cancelled outright: a
   card that jumps 3px with no easing is not "less motion", it is a twitch.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --hwd-transition: 0s;
    --hwd-transition-mid: 0s;
    --hwd-transition-fade: 0s;
    --hwd-transition-slow: 0s;
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  .hwd-search-form button[type="submit"]:hover,
  .hwd-service:hover,
  .hwd-btn-primary:hover,
  .hwd-btn-dark:hover,
  .hwd-sc-card:hover,
  .hwd-blog-grid__item:hover,
  .hwd-hero-icon:hover img,
  .hwd-hero-icon:hover [class*="fa-"],
  .hwd-sc-card:hover .hwd-sc-card-media img,
  a.hwd-pf-card:hover,
  a.hwd-pf-card:hover .hwd-pf-media img { transform: none; }

  .hwd-pf-go { opacity: 1; transform: none; }
}

/* ============================================================
   11. PRINT
   ============================================================ */
@media print {
  .hwd-topbar,
  .hwd-header-top,
  .hwd-header-strip,
  .hwd-header-nav,
  .hwd-header-bottom,
  .hwd-navbar,
  .hwd-mobile-nav,
  .hwd-search-modal,
  .hwd-backtop,
  .hwd-skip-link,
  .hwd-sidebar-left,
  .hwd-sidebar-right,
  .hwd-hero-prev,
  .hwd-hero-next,
  .hwd-hero-dots,
  .hwd-slider-pause,
  .hwd-ab-share,
  .hwd-ab-edit,
  .hwd-copyright,
  .hwd-footer,
  .hwd-band,
  .hwd-section { display: none !important; }

  /* Paper is light whatever theme is on screen: the scheme switch in
     dark.css is outweighed here, so every light-dark() token resolves light
     and the light logo is the one that prints. */
  html[lang][dir] { color-scheme: light; }
  html[lang][dir] .hwd-logo-img--light { display: block; }
  html[lang][dir] .hwd-logo-img--dark { display: none; }

  /* The brand stays at the top of the printed page; the controls around it go. */
  .hwd-header,
  .hwd-frontpage .hwd-header {
    position: static;
    background: none;
    box-shadow: none;
  }

  .hwd-logo-tagline { display: none; }

  /* Print is the one surface that is not a theme: paper is white, ink is black,
     and no generated ramp applies. These two are literals on purpose. */
  body {
    background: #fff;
    color: #000;
    font-size: 12pt;
  }

  .hwd-container,
  .hwd-grid,
  .hwd-ab-layout {
    max-width: none;
    padding: 0;
  }

  .hwd-ab-layout { display: block; }

  .hwd-component,
  .hwd-sc-card,
  .hwd-blog-grid__item {
    border: 0;
    background: none;
    box-shadow: none;
  }

  .hwd-ab-content a::after,
  .hwd-sc-card-body a::after { content: " (" attr(href) ")"; font-size: 9pt; }

  .hwd-ab-content a[href^="#"]::after,
  .hwd-ab-content a[href^="javascript:"]::after { content: ""; }

  h1, h2, h3, h4, h5, h6 { break-after: avoid; }
  img, figure, blockquote, pre, table { break-inside: avoid; }
}
