/*
 * Webdev Zimbabwe — umbrella / router template (v2026)
 * Load AFTER webdev-base.css. Shared by the category umbrella pages:
 *   /email-office · /websites · /hosting · /vps-server-hosting
 *
 * Block order follows page-architecture "Umbrella/router":
 *   1 category framing · 2 choice grid · 3 existing-customer intercept
 *   4 compact trust · 5 human fallback
 *
 * The routing cards are the principal CTAs — everything else on the page is
 * subordinate to getting the visitor into the right child page.
 *
 * Hero, chips, pillars, FAQ and the .wd-final banner all come from
 * webdev-base.css.
 */

/* ---------- choice grid ---------- */

.wd-choices {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.wd-choice {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
}

/*
 * Icon and product name, side by side and never stacked.
 *
 * This was a wrapping flex row, which broke the moment a name was long: on
 * /vps-server-hosting, "Enterprise & Custom Infrastructure" wrapped onto the
 * line BELOW its icon, so that card's name — and every line under it — sat
 * lower than in its neighbours. A two-column grid keeps the name beside the
 * icon and lets it wrap within its own column instead.
 *
 * min-height reserves two lines of the heading. Card grids give each card its
 * own row track, so nothing else makes a one-line name and a two-line name
 * occupy the same height, and without it the copy below still steps out of
 * line. Centred, so a one-line name sits mid-block rather than riding the top.
 */
.wd-choice__top {
  align-items: center;
  column-gap: 0.75rem;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  min-height: 3rem;
  row-gap: 0.75rem;
}

/*
 * Brand mark. Height is fixed but width is free: these are supplied logos with
 * very different aspect ratios — Zoho and Microsoft are near-square, the Google
 * Workspace file is a wide lockup. A square box shrank the wide one to a
 * fraction of the others, so only the height is constrained.
 *
 * `height` is !important because custom.css carries a global
 * `li img { height: 42px !important }` above 768px that would otherwise clamp
 * any logo placed inside a list.
 */
.wd-choice__logo {
  align-items: center;
  display: inline-flex;
  flex: 0 0 auto;
  height: 2.25rem;
  justify-content: flex-start;
  max-width: 8rem;
}

.wd-choice__logo img {
  height: 100% !important;
  max-width: 100%;
  object-fit: contain;
  width: auto;
}

/*
 * Tag always sits on its own row, so cards with longer names don't put it
 * inline while the others push it down. It spans both grid columns to force
 * that break (it was `flex-basis: 100%` while this block was a flex row);
 * `max-width: max-content` stops it stretching into a full-width bar.
 */
.wd-choice__top .wd-tag {
  grid-column: 1 / -1;
  max-width: max-content;
}

.wd-choice h3 {
  font-size: clamp(1.0625rem, 1.4vw, 1.1875rem);
  margin-right: auto;
}

.wd-choice .wd-body {
  margin-top: 0;
}

/* Price anchor — dynamic token only, never a remembered value. */
.wd-choice__price {
  border-top: 1px solid var(--wd-grey-100);
  margin: 0;
  padding-top: 0.875rem;
}

.wd-choice__price span {
  color: var(--wd-grey-500);
  display: block;
  font-size: 0.8125rem;
}

.wd-choice__price b {
  color: var(--wd-charcoal-900);
  font-size: 1.0625rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.wd-choice__price em {
  color: var(--wd-grey-500);
  font-size: 0.8125rem;
  font-style: normal;
}

.wd-choice__includes {
  display: grid;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.wd-choice__includes li {
  align-items: center;
  color: var(--wd-grey-700);
  display: flex;
  font-size: 0.875rem;
  gap: 0.5rem;
}

.wd-choice__includes .wd-icon {
  color: var(--wd-success-600);
  height: 1.0625rem;
  width: 1.0625rem;
}

/*
 * One action per card — the routing decision, nothing competing with it.
 *
 * It is a SPAN, not an anchor: the whole card is already the link, so a nested
 * <a> would be invalid and would split the click target. It therefore has to
 * reproduce the .wd-btn--primary look by hand rather than take the class, and
 * the values below are copied from that component so the two stay identical.
 */
.wd-choice__go {
  align-items: center;
  background: var(--wd-orange-500);
  border: 1px solid var(--wd-orange-500);
  border-radius: var(--wd-radius-pill);
  box-shadow: var(--wd-shadow-xs);
  color: var(--wd-white);
  display: flex;
  font: 600 0.94rem/1 var(--wd-font-sans);
  gap: 0.5rem;
  justify-content: center;
  margin-top: auto;
  min-height: 44px;
  padding: 0.75rem 1.25rem;
  text-decoration: none;
  transition:
    background-color var(--wd-duration) var(--wd-ease),
    border-color var(--wd-duration) var(--wd-ease),
    box-shadow var(--wd-duration) var(--wd-ease);
}

.wd-choice__go .wd-icon {
  transition: transform var(--wd-duration) var(--wd-ease);
}

@media (hover: hover) and (pointer: fine) {
  /* Matches .wd-btn--primary:hover. The !important answers custom.css, which
     carries a global `a:hover { text-decoration: none }` and colour rules. */
  .wd-choice__go:hover {
    background: var(--wd-orange-600);
    border-color: var(--wd-orange-600);
    box-shadow: var(--wd-shadow-sm);
    color: var(--wd-white) !important;
  }

  /* The whole card is the link, so hovering anywhere on it must move the
     button too — not only a direct hover on the pill itself. */
  .wd-choice:hover .wd-choice__go {
    background: var(--wd-orange-600);
    border-color: var(--wd-orange-600);
    box-shadow: var(--wd-shadow-sm);
    color: var(--wd-white) !important;
  }

  .wd-choice__go:hover .wd-icon,
  .wd-choice:hover .wd-choice__go .wd-icon {
    transform: translateX(4px);
  }
}

.wd-choice__go:focus-visible {
  border-radius: var(--wd-radius-sm);
  box-shadow: var(--wd-focus);
  outline: 0;
}

/* Comparison table lives in webdev-base.css — shared with the product pages. */

/* ---------- "still not sure" chooser ---------- */

.wd-chooser {
  align-items: center;
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr) auto;
}

.wd-chooser h2 {
  font-size: clamp(1.375rem, 2.2vw, 1.75rem);
}

/*
 * ART variant — illustration left, the chooser panel right, both inside one card.
 *
 * A modifier, not a change to .wd-chooser: /hosting uses the plain three-column
 * row and has no illustration to give it.
 *
 * The card’s own padding is kept (unlike .wd-splitcard, which bleeds its art to
 * the edge) because this illustration is not a photograph — it already contains
 * a rounded dark panel with its own light margin, and bleeding it would crop
 * that margin off and leave the panel’s corners cut by the card’s radius.
 */
.wd-chooser--art {
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
}

/*
 * Painted --wd-warm-050 (#fafaf8) to match the illustration’s own margin, which
 * runs #f8f8f8–#fcfaf8 across its corners. On the card’s white this would
 * otherwise read as a faint rectangle around the image.
 */
.wd-chooser__art {
  background: var(--wd-warm-050);
  border-radius: var(--wd-radius-md);
  display: block;
  height: auto;
  width: 100%;
}

.wd-chooser__panel {
  display: grid;
  gap: 0.875rem;
  justify-items: start;
}

.wd-chooser--art .wd-chooser__options {
  width: 100%;
}

/* A row is a bordered rail: mark, label, arrow. */
.wd-chooser--art .wd-chooser__options a {
  align-items: center;
  border: 1px solid var(--wd-grey-200);
  border-radius: var(--wd-radius-md);
  color: var(--wd-charcoal-900);
  display: grid;
  gap: 0.875rem;
  grid-template-columns: auto minmax(0, 1fr) auto;
  padding: 0.875rem 1.125rem;
  text-decoration: none;
  transition:
    border-color var(--wd-duration) var(--wd-ease),
    box-shadow var(--wd-duration) var(--wd-ease);
}

.wd-chooser__mark {
  color: var(--wd-orange-500);
  height: 1.5rem;
  width: 1.5rem;
}

.wd-chooser__go {
  color: var(--wd-orange-500);
  transition: transform var(--wd-duration) var(--wd-ease);
}

@media (hover: hover) and (pointer: fine) {
  .wd-chooser--art .wd-chooser__options a:hover {
    border-color: var(--wd-orange-500);
    box-shadow: 0 8px 20px 0 rgb(17 20 22 / 10%);
  }

  .wd-chooser--art .wd-chooser__options a:hover .wd-chooser__go {
    transform: translateX(4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .wd-chooser__go {
    transform: none !important;
    transition: none;
  }
}

/* Side by side needs real width for both halves; below this the illustration
   goes on top and the panel runs full width. */
@media (max-width: 767.98px) {
  .wd-chooser--art {
    grid-template-columns: minmax(0, 1fr);
  }
}

.wd-chooser__options {
  display: grid;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.wd-chooser__options a {
  align-items: center;
  background: var(--wd-white);
  border: 1px solid var(--wd-grey-200);
  border-radius: var(--wd-radius-sm);
  color: var(--wd-charcoal-900);
  display: flex;
  font-size: 0.9375rem;
  font-weight: 600;
  gap: 0.75rem;
  justify-content: space-between;
  min-height: 52px;
  padding: 0.625rem 1rem;
  text-decoration: none;
  transition:
    border-color var(--wd-duration) var(--wd-ease),
    box-shadow var(--wd-duration) var(--wd-ease);
}

@media (hover: hover) and (pointer: fine) {
  .wd-chooser__options a:hover {
    border-color: var(--wd-orange-500);
    box-shadow: var(--wd-shadow-sm);
  }
}

.wd-chooser__options a:focus-visible {
  box-shadow: var(--wd-focus);
  outline: 0;
}

.wd-chooser__options .wd-icon {
  color: var(--wd-orange-600);
}

/* ---------- responsive ---------- */

@media (max-width: 1099.98px) {
  .wd-chooser {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 991.98px) {
  .wd-choices {
    grid-template-columns: minmax(0, 1fr);
  }
}

/*
 * Behavioural question above the product name, as on the /upgrades router.
 * Buyers scan for the description of their own situation, not the SKU.
 */
.wd-choice__q {
  color: var(--wd-orange-700);
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0;
}

/*
 * Who manages it — the axis this router splits on. Sits under the product name
 * so the visitor reads the name, then immediately the commitment it implies.
 */
.wd-choice__kind {
  color: var(--wd-orange-700);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  margin: -0.375rem 0 0;
  text-transform: uppercase;
}

/* ---------- illustrated choice card (.wd-choice--media) ----------
 * Opt-in variant, currently /websites only — the other router pages keep the
 * icon-and-title card. An inset illustration panel sits on top; below it a
 * pill for who does the work, the product name over a hairline, a "Best for"
 * line and the description, with the button pinned to the bottom so every
 * card in the row lines up.
 *
 * `.wd-page .wd-choice--media` matches `.wd-page .wd-card` in base and wins on
 * load order, which is what drops the card padding to the thinner inset.
 */
.wd-page .wd-choice--media {
  gap: 0;
  padding: clamp(0.875rem, 1.4vw, 1.25rem);
}

.wd-choice__media {
  aspect-ratio: 16 / 9;
  background: var(--wd-grey-100);
  border-radius: var(--wd-radius-md);
  display: block;
  overflow: hidden;
}

.wd-choice__media img {
  display: block;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms var(--wd-ease);
  width: 100%;
}

/* Text sits further in than the illustration, as in the client's reference. */
.wd-choice__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 0.875rem;
  padding: clamp(1.25rem, 2vw, 1.625rem) clamp(0.375rem, 1vw, 0.875rem) clamp(0.375rem, 1vw, 0.75rem);
}

/* Who does the work, as a soft pill. */
.wd-choice--media .wd-choice__kind {
  align-self: flex-start;
  background: var(--wd-orange-050);
  border-radius: var(--wd-radius-pill);
  letter-spacing: 0.06em;
  margin: 0;
  padding: 0.4375rem 0.875rem;
}

/* `margin: 0` also clears `.wd-choice h3 { margin-right: auto }`, which in this
   column layout would shrink the heading — and its rule — to the text width. */
.wd-choice--media h3 {
  border-bottom: 1px solid var(--wd-grey-200);
  font-size: clamp(1.25rem, 1.8vw, 1.5rem);
  margin: 0;
  padding-bottom: 0.875rem;
}

.wd-choice__best {
  color: var(--wd-orange-700);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.45;
  margin: 0;
}

.wd-choice__best span {
  color: var(--wd-grey-500);
  display: block;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  margin-bottom: 0.375rem;
  text-transform: uppercase;
}

@media (hover: hover) and (pointer: fine) {
  .wd-choice--media:hover .wd-choice__media img {
    transform: scale(1.03);
  }
}

@media (prefers-reduced-motion: reduce) {
  .wd-choice__media img,
  .wd-choice--media:hover .wd-choice__media img {
    transform: none;
    transition: none;
  }
}

/* One card per row on tablets: stacked, a 16:9 illustration would be ~500px
   tall, so the card goes side by side — illustration left, copy right. */
@media (min-width: 576px) and (max-width: 991.98px) {
  .wd-page .wd-choice--media {
    align-items: center;
    column-gap: 1.25rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  }

  .wd-choice--media .wd-choice__body {
    padding: 0.25rem 0.5rem 0.25rem 0;
  }
}

/* ---------- consultative choice card ----------
 * The enterprise route is a conversation, not a checkout, so this variant made
 * its card dark: a different KIND of option rather than a more expensive tier.
 * Everything the light card sets in a dark ink is re-stated here.
 *
 * NOTHING OPTS IN ANY MORE. The client asked for the consultative card to match
 * its siblings, so /vps-server-hosting, /websites and /website-builder dropped
 * the class and all three router cards are now white. Kept as a hook, like
 * .wd-route--lead in webdev-upgrades.css, in case the distinction is wanted
 * back — but if you are hunting a dark card on a router page, it is not this.
 */
.wd-choice--dark {
  background: var(--wd-charcoal-950);
  color: var(--wd-white);
}

.wd-choice--dark h3 {
  color: var(--wd-white);
}

.wd-choice--dark .wd-choice__kind {
  color: var(--wd-orange-500);
}

.wd-choice--dark .wd-choice__q {
  color: var(--wd-orange-500);
}

/*
 * .wd-body and the includes list both carry their own dark colour, which beats
 * the white inherited from the card — a direct rule always wins over an
 * inherited one. Without both of these the copy renders dark-grey on near-black,
 * which is a contrast failure rather than a cosmetic one.
 */
.wd-choice--dark .wd-body,
.wd-choice--dark .wd-choice__includes li {
  color: var(--wd-grey-200);
}

/* The dark card takes the same filled pill — no override needed beyond the
   inherited colour, which the button already sets to white. */

.wd-choice--dark .wd-icon-plate {
  color: var(--wd-orange-500);
}

/* ---------- three-across trust row ----------
 * Breakpoints mirror base's .wd-pillars exactly so its `li:nth-child(odd)` and
 * `li + li` divider resets still line up. router.css loads after base, so these
 * win the source-order tie inside those media queries.
 */
.wd-pillars--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 1099.98px) {
  .wd-pillars--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 2rem;
  }
}

@media (max-width: 575.98px) {
  .wd-pillars--three {
    grid-template-columns: minmax(0, 1fr);
  }
}

/*
 * Icon beside the copy rather than above it. With only three items the row is
 * wide enough for a horizontal pairing, which reads faster than a stacked one.
 * The icon spans both text rows so the heading and its line-up stay level.
 */
.wd-pillars--inline li {
  align-items: start;
  column-gap: 1rem;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
}

.wd-pillars--inline .wd-icon {
  grid-row: 1 / span 2;
  margin-bottom: 0;
}

/*
 * Banner with no icon. The base three-column grid is `auto | 1fr | auto` and
 * expects an art element first — drop it and the copy would be sized `auto`
 * while the buttons took the flexible column.
 */
.wd-final--noart {
  grid-template-columns: minmax(0, 1fr) auto;
}

/* Trailing secondary link under the intercept's main action. */
.wd-final__link {
  align-items: center;
  color: var(--wd-orange-700);
  display: inline-flex;
  font-weight: 600;
  gap: 0.5rem;
  justify-content: center;
  min-height: 44px;
}

.wd-final__link:hover,
.wd-final__link:focus-visible {
  color: var(--wd-orange-700) !important;
  text-decoration: underline !important;
  text-underline-offset: 0.22em;
}

/*
 * A supplied brand logo standing in for the outline mark, in the same 2.75rem
 * box so headings stay on one baseline across the row. The logo keeps its own
 * brand colour — it identifies a third-party product, so it is not recoloured
 * into the palette.
 *
 * `height` is !important for the same reason as .wd-choice__logo img:
 * custom.css carries a global `li img { height: 42px !important }` above 768px
 * that clamps any image placed inside a list.
 */
.wd-icon-plate--logo img {
  height: 100% !important;
  max-width: 100%;
  object-fit: contain;
  width: auto;
}

/* ---------- per-page hero artwork ----------
 * .wd-subhero--servers MOVED to webdev-base.css — /hosting (this template) and
 * /web-hosting (the product template) share the same artwork, and base is the
 * only layer both pages load.
 */

/* Stacks the intercept's two actions. */
.wd-final__actions--stack {
  display: grid;
  gap: 0.25rem;
  justify-items: stretch;
}

/* ---------- feature card grid ----------
 * The "what's included" inventory. A card grid rather than the bare icon rows
 * the product template uses: there are twelve items here, and without a surface
 * per item the block reads as one undifferentiated wall of text.
 */
.wd-featgrid {
  display: grid;
  gap: clamp(0.75rem, 1.5vw, 1rem);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.wd-featgrid .wd-icon {
  color: var(--wd-orange-600);
  margin-bottom: 0.625rem;
}

.wd-featgrid h3 {
  font-size: 0.9375rem;
}

.wd-featgrid p {
  color: var(--wd-grey-700);
  font-size: 0.875rem;
  margin: 0.375rem 0 0;
}

/*
 * HOVER on the content cards — the "what's included" inventory, the four split
 * cards, and the three use-case cards.
 *
 * None of them lead anywhere — no link, no button — so this deliberately stops
 * short of the 4px "pickable" lift webdev-base.css reserves for cards that do.
 * 2px and an orange edge reads as "you are here" rather than "click me", which
 * keeps that distinction doing its job.
 *
 * The orange edge costs no layout: .wd-card already ships `border: 1px solid
 * transparent` for exactly this, so colouring it moves nothing by a pixel. On a
 * use-case card the 3px orange rule along the top simply continues round.
 *
 * Reduced motion needs nothing here: webdev-base.css forces `.wd-page .wd-card`
 * to `transform: none`, and these all carry .wd-card. The colour changes are
 * left alone under that setting, a colour change being no kind of motion.
 */
@media (hover: hover) and (pointer: fine) {
  /* Outranks `.wd-page .wd-card` (0,2,0), whose transition lists only shadow
     and transform. */
  .wd-page .wd-featgrid .wd-card,
  .wd-page .wd-usecards .wd-card {
    /* Client direction. Worth knowing it is here: these cards have no link and
       no button, so the hand promises a click that nothing answers. Inside the
       hover query, so a touch device — which has no cursor to show — is
       unaffected. Delete this one line if the cards ever need to read as inert
       again, or give them a destination and move them to .wd-card--interactive. */
    cursor: pointer;
    transition:
      border-color var(--wd-duration) var(--wd-ease),
      box-shadow var(--wd-duration) var(--wd-ease),
      transform var(--wd-duration) var(--wd-ease);
  }

  .wd-page .wd-featgrid .wd-card:hover,
  .wd-page .wd-usecards .wd-card:hover {
    border-color: var(--wd-orange-500);
    box-shadow: 0 12px 26px 0 rgb(17 20 22 / 14%);
    transform: translateY(-2px);
  }

  /*
   * Accent colours, listed per component rather than as one blanket rule.
   *
   * A use-case card contains its own .wd-icon set — the green ticks down the
   * feature list — and those are green ON PURPOSE. Sweeping every .wd-icon into
   * the orange would turn "confirmed" into brand decoration, so only the label
   * and the heading move here.
   */
  .wd-featgrid .wd-card h3,
  .wd-featgrid .wd-card .wd-icon,
  .wd-featgrid .wd-card .wd-featgrid__icon,
  .wd-usecard h3,
  .wd-usecard__label {
    transition: color var(--wd-duration) var(--wd-ease);
  }

  .wd-featgrid .wd-card:hover h3,
  .wd-usecard:hover h3 {
    color: var(--wd-orange-600);
  }

  .wd-featgrid .wd-card:hover .wd-icon,
  .wd-featgrid .wd-card:hover .wd-featgrid__icon,
  .wd-usecard:hover .wd-usecard__label {
    color: var(--wd-orange-500);
  }
}

/*
 * SPLIT CARD — copy on the left, illustration bled to the right edge.
 *
 * Used by the four "what we can build" cards. The padding moves off the card and
 * onto __body, which is the only way the art can reach the card edge; .wd-card
 * keeps its radius and `overflow: hidden` clips the image to it.
 *
 * The padding override needs .wd-page to outrank `.wd-page .wd-card` (0,2,0) in
 * webdev-base.css — a bare .wd-splitcard (0,1,0) would lose and the art would sit
 * in a 2.25rem well.
 *
 * CONTAIN, not cover. Grid rows stretch, so a card is as tall as the tallest in
 * its row, and with this copy running to five lines the media slot ends up
 * PORTRAIT — roughly 0.7:1 against a 4:3 source. Cover then ate about half the
 * width of every illustration: the magnifier and the monitor were both sliced.
 *
 * Contain guarantees nothing is cut at any card height. The cost is margin above
 * and below, so the panel is painted in the illustration’s own backdrop and the
 * margin disappears into it. Sampled from the files themselves: three sit on
 * cream (#fcf4e1–#feead2 across their corners) and web1 on charcoal
 * (#1d2124–#2d3035). The flats below are mid-range, close enough that the
 * images’ soft gradients meet them without a visible seam.
 *
 * Re-sample the corners before swapping any of these files.
 */
.wd-page .wd-featgrid .wd-splitcard {
  align-items: stretch;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.5fr);
  overflow: hidden;
  padding: 0;
}

.wd-splitcard__body {
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
}

/* No `height: !important` needed: this image is not inside a <li>, so Antler’s
   `li img { height: 42px !important }` never reaches it. */
.wd-splitcard__media {
  background: #fdefdb;
  display: block;
  height: 100%;
  object-fit: contain;
  width: 100%;
}

/* The integrations illustration is the only one drawn on a dark ground. */
.wd-splitcard__media--dark {
  background: #26292d;
}

/*
 * Below 992px the grid is still two across, so the card is roughly 470px wide and
 * a 0.42fr column leaves the art about 140px — too narrow to read as anything.
 * Stack instead, and give the image a band of its own.
 */
@media (max-width: 991.98px) {
  .wd-page .wd-featgrid .wd-splitcard {
    grid-template-columns: minmax(0, 1fr);
  }

  .wd-splitcard__media {
    aspect-ratio: 16 / 9;
    height: auto;
  }
}

/* Two across, for the four "what we can build" cards. */
.wd-featgrid--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.wd-featgrid--two h3 {
  font-size: 1.0625rem;
}

.wd-featgrid--two p {
  font-size: 0.9375rem;
}

@media (max-width: 991.98px) {
  .wd-featgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 575.98px) {
  .wd-featgrid,
  .wd-featgrid--two {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- local payment methods ----------
 * Client-supplied brand lockups for EcoCash, O'mari, InnBucks and Zimswitch
 * Online, replacing the wordmark tiles this section used before the assets were
 * cleared. Used only by /websites.
 */
/* Copy on the left, the method tiles on the right. */
.wd-paysplit {
  align-items: center;
  display: grid;
  gap: clamp(1.5rem, 3vw, 3rem);
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
}

.wd-paysplit h2 {
  font-size: clamp(1.375rem, 2.2vw, 1.75rem);
}

@media (max-width: 991.98px) {
  .wd-paysplit {
    grid-template-columns: minmax(0, 1fr);
  }
}

/*
 * One badge, not a tile grid.
 *
 * Paynow is the gateway the local methods settle through, and its badge is a
 * single lockup that already shows what it accepts. That retires the four
 * provider tiles and, with them, the white plates behind each mark -- those
 * existed only because EcoCash, O’mari, InnBucks and Zimswitch each carry dark
 * elements that vanish on a black panel.
 *
 * The LIGHT variant is drawn in white and pale blue for a dark surface, so it
 * sits straight on .wd-panel--black with nothing behind it.
 *
 * No `height: !important` here, unlike the tiles this replaces. That was needed
 * only because Antler’s custom.css ships `li img { height: 42px !important }`
 * above 768px, and this image is no longer inside a <li>.
 *
 * The badge is 3444x888 (3.88:1). max-width caps it so it cannot outgrow the
 * copy beside it in the narrower grid column; width:100% lets it shrink when
 * .wd-paysplit collapses to one column below 992px.
 */
.wd-paybadge {
  display: block;
  height: auto;
  margin-inline: auto;
  max-width: 28rem;
  width: 100%;
}

/* .wd-steps__list--six MOVED to webdev-base.css -- the consultative template
 * needed it too. */

/* ---------- operating-model use cases ---------- */

.wd-usecards {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* The orange rule reads as a tab on top of the card. */
.wd-usecard {
  border-top: 3px solid var(--wd-orange-500);
}

.wd-usecard__label {
  color: var(--wd-grey-500);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  margin: 0;
  text-transform: uppercase;
}

.wd-usecard h3 {
  font-size: 1.125rem;
  margin-top: 0.375rem;
}

.wd-usecard > p {
  color: var(--wd-grey-700);
  font-size: 0.9375rem;
}

.wd-usecard ul {
  display: grid;
  gap: 0.5rem;
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
}

.wd-usecard li {
  align-items: start;
  color: var(--wd-grey-700);
  display: grid;
  font-size: 0.9375rem;
  gap: 0.625rem;
  grid-template-columns: 1.125rem 1fr;
}

.wd-usecard li .wd-icon {
  color: var(--wd-success-600);
  height: 1.125rem;
  margin-top: 0.1875rem;
  width: 1.125rem;
}

@media (max-width: 991.98px) {
  .wd-usecards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- two-route choice grid ----------
 * .wd-choices is three across. Where a page routes between exactly two options
 * they should fill the row rather than leaving a third of it empty.
 */
.wd-choices--two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 767.98px) {
  .wd-choices--two {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- secondary router row ----------
 * /hosting routes to three hosting tiers, then to Enterprise Infrastructure and
 * Domains below them. Those two are a different KIND of choice — one
 * consultative, one a domain purchase — so they are centred and capped in width
 * rather than stretched into a second full-width band that would read as two
 * more hosting tiers. .wd-choices--two already supplies the column count and
 * the mobile collapse; this adds only the centring.
 */
.wd-choices__subhead {
  color: var(--wd-grey-500);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  margin: clamp(1.75rem, 3vw, 2.5rem) 0 clamp(0.75rem, 1.5vw, 1rem);
  text-align: center;
  text-transform: uppercase;
}

@media (min-width: 992px) {
  .wd-choices--sub {
    grid-template-columns: repeat(2, minmax(0, 24rem));
    justify-content: center;
  }
}

/* Short code badge beside a route name, e.g. ZS / ZC. */
.wd-choice__code {
  align-items: center;
  border: 1px solid var(--wd-orange-500);
  border-radius: 50%;
  color: var(--wd-orange-700);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: 0.6875rem;
  font-weight: 700;
  height: 2rem;
  justify-content: center;
  letter-spacing: 0.02em;
  width: 2rem;
}

.wd-choice--dark .wd-choice__code {
  color: var(--wd-orange-500);
}

/* ---------- three-across feature grid ----------
 * MUST come after the .wd-featgrid @media blocks above: media queries add no
 * specificity, so --three (0,1,0) and .wd-featgrid (0,1,0) tie and source order
 * decides. Breakpoints mirror the base ones so nothing is left half-applied.
 */
.wd-featgrid--three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 991.98px) {
  .wd-featgrid--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 575.98px) {
  .wd-featgrid--three {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Icon slot on a feature card. Was a 01-06 sequence label until QA4 B35
   replaced the numbers with icons; a number that is no longer a number has no
   sequence to carry. Keeps the old colour so the cards read the same, and a
   slightly larger bottom margin because an icon is taller than a 11px label. */
.wd-featgrid__icon {
  color: var(--wd-orange-600);
  display: block;
  margin: 0 0 0.5rem;
}

/* ---------- connected-app tiles ----------
 * Named apps in circles. Text, not logos: we hold no cleared brand assets for
 * the individual Zoho applications, and unlicensed marks on a commercial page
 * are a risk a wordmark avoids (content-guardrails §4).
 */
.wd-apptiles {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.wd-apptiles li {
  align-items: center;
  border: 1px solid rgb(255 255 255 / 16%);
  border-radius: var(--wd-card-radius);
  display: grid;
  gap: 0.625rem;
  justify-items: center;
  padding: 1.125rem 0.75rem;
  text-align: center;
}

.wd-apptiles__mark {
  align-items: center;
  border: 1px solid var(--wd-orange-500);
  border-radius: 50%;
  color: var(--wd-orange-500);
  display: inline-flex;
  font-size: 0.6875rem;
  font-weight: 700;
  height: 2.5rem;
  justify-content: center;
  width: 2.5rem;
}

/*
 * Logo variant of the mark. The circle keeps its size and shape; what changes
 * is that it becomes a white plate holding a supplied product logo instead of
 * an orange initials badge.
 *
 * The plate is not decoration. This row sits on the dark panel, and several
 * Zoho marks are mid-blue or near-black — legible on white, invisible on the
 * panel — and a vendor logo may not be recoloured. Same reasoning as the
 * partner wall further up this file.
 *
 * `height: 100% !important` for the same reason as .wd-choice__logo img:
 * custom.css carries a global `li img { height: 42px !important }` above
 * 768px, and these marks are inside list items.
 */
.wd-apptiles__mark--logo {
  background: var(--wd-white);
  border-color: transparent;
  padding: 0.375rem;
}

.wd-apptiles__mark--logo img {
  height: 100% !important;
  max-width: 100%;
  object-fit: contain;
  width: auto;
}

.wd-apptiles span {
  font-size: 0.875rem;
  font-weight: 600;
}

@media (max-width: 991.98px) {
  .wd-apptiles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 479.98px) {
  .wd-apptiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------- /email-office hero ----------
 * Client-supplied artwork. Defined here rather than in webdev-product.css,
 * where the other mail heroes live, because /email-office loads the router
 * layer and not the product one — putting it there would silently do nothing.
 *
 * The JPEG, not the supplied PNG: the original was an indexed 256-colour PNG at
 * 307KB. Re-encoded it is 145KB with full colour, so it is both smaller and
 * cleaner across the large flat wall area where indexed palettes band. The PNG
 * is left in place untouched.
 *
 * Composition suits the default `right center` focal point: the laptop and
 * hands sit right, the desk and wall on the left are empty, which is where the
 * heading and the scrim land.
 */
.wd-subhero--office {
  --wd-subhero-art: url("../img/emailandoffice.jpg");
}

/* .wd-subhero--websites MOVED to webdev-base.css — /websites (this template),
 * /managed-websites (product) and /custom-websites (consult) all share the art,
 * and base is the only layer all three load. */


/*
 * ART variant -- an illustration band at the top of each choice card.
 *
 * A modifier: .wd-choice is shared with /email-office, /hosting and
 * /website-builder, and only /vps-server-hosting has the artwork.
 *
 * The icon plate and its .wd-choice__top wrapper are gone from the markup here
 * -- the illustration says what the mark said -- and the kind label moves above
 * the heading, which is the order the design asks for.
 */
.wd-page .wd-choices--art .wd-choice {
  display: grid;
  grid-template-rows: auto 1fr;
  overflow: hidden;
  padding: 0;
}

/*
 * 16:9 matches the sources exactly, so nothing is cropped. Background shows
 * only while the image loads -- these are opaque renders on their own peach
 * ground (#fcf0e5-#fef0e4 sampled across the three).
 */
.wd-choice__art {
  aspect-ratio: 16 / 9;
  background: var(--wd-orange-050);
  display: block;
  min-height: 0;
  overflow: hidden;
}

.wd-choice__art img {
  display: block;
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.wd-choice__body {
  align-content: start;
  display: grid;
  gap: 0.5rem;
  min-height: 0;
  padding: clamp(1.125rem, 2vw, 1.5rem);
}

/* Was a <p> above the heading in a flex row; now a label leading the stack. */
.wd-choices--art .wd-choice__kind {
  margin: 0;
}

.wd-choices--art .wd-choice h3 {
  margin: 0;
}

/* Pinned to the foot so the three calls line up across the row. */
.wd-choices--art .wd-choice__go {
  margin-top: auto;
  padding-top: 0.25rem;
}

/*
 * Buttons level across the row (review: buttons align on cards).
 *
 * `margin-top: auto` above only pins the button in a flex column. The body is
 * a grid (.wd-choice__body, just above), where each row is as tall as its
 * content, so the button sat straight under the copy and the three calls on
 * /vps-server-hosting and /websites landed up to 50px apart. Same gap, same
 * padding, same order: only the layout mode changes, on the two picture
 * variants where the cards differ in copy length.
 */
.wd-choices--art .wd-choice__body,
.wd-choice--media .wd-choice__body {
  display: flex;
  flex-direction: column;
}

/* The label spanned the card while the body was a grid. Kept that way, so the
   button is the only thing that moves. */
.wd-choice--media .wd-choice__body > .wd-choice__kind {
  align-self: stretch;
}

/*
 * ART variant of the banner -- illustration, copy, actions.
 *
 * .wd-final is on twelve pages and .wd-on-brand on fourteen, so this is a
 * modifier on one instance rather than a change to either. The orange
 * .wd-on-brand surface is dropped here: the card is light, and the emphasis
 * moves to a filled primary button in the actions column.
 *
 * Base .wd-final is `auto minmax(0,1fr) auto` for icon / copy / actions. The
 * icon becomes a full-bleed picture panel, so its track is given a real width.
 */
.wd-page .wd-final--art {
  align-items: stretch;
  gap: 0;
  grid-template-columns: minmax(0, 0.28fr) minmax(0, 1fr) auto;
  overflow: hidden;
  padding: 0;
}

.wd-final--art .wd-final__art {
  background: var(--wd-orange-050);
  display: block;
  min-height: 0;
  overflow: hidden;
}

/*
 * `height` is !important for the usual reason -- Antler's custom.css forces
 * `li img` to 42px above 768px. This banner is not in a list today, but the
 * component is used inside one elsewhere, and the guard costs nothing.
 */
.wd-final--art .wd-final__art img {
  display: block;
  height: 100% !important;
  object-fit: cover;
  width: 100%;
}

.wd-final__copy {
  align-content: center;
  display: grid;
  gap: 0.5rem;
  padding: clamp(1.25rem, 2.5vw, 2rem);
}

.wd-final--art .wd-final__copy .wd-body {
  color: var(--wd-grey-700);
  margin: 0;
}

/* The rule separates the offer from the actions, as the design shows. */
.wd-page .wd-final--art .wd-final__actions {
  align-content: center;
  border-left: 1px solid var(--wd-grey-200);
  display: grid;
  gap: 0.875rem;
  justify-items: center;
  margin: clamp(1.25rem, 2.5vw, 2rem) 0;
  padding: 0 clamp(1.25rem, 2.5vw, 2rem);
}

/*
 * Stack below 992px: three columns leave the picture a sliver and the copy a
 * column too narrow to read. The art becomes a band across the top.
 */
@media (max-width: 991.98px) {
  .wd-page .wd-final--art {
    grid-template-columns: minmax(0, 1fr);
  }

  .wd-final--art .wd-final__art {
    aspect-ratio: 16 / 6;
  }

  .wd-page .wd-final--art .wd-final__actions {
    border-left: 0;
    border-top: 1px solid var(--wd-grey-200);
    justify-items: start;
    margin: 0 clamp(1.25rem, 2.5vw, 2rem);
    padding: clamp(1.25rem, 2.5vw, 2rem) 0;
  }
}