/* ==========================================================================
   SmartEdge — service pages
   Loaded only on the eight service category pages and the individual service
   pages beneath them, so no other page pays for this file.

   Everything here builds on the existing design system in main.css and
   components.css: the same container width, type scale, radius, shadow, button
   treatment and blue/orange tokens. The AI package's approved light direction
   is respected: this file introduces no dark section surface anywhere.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Hero
   -------------------------------------------------------------------------- */
.se-sphero{position:relative;overflow:hidden;background:linear-gradient(160deg,var(--se-blue-soft) 0%,#fff 58%);border-bottom:1px solid var(--se-line-soft)}
.se-sphero::after{content:'';position:absolute;inset:0;background:radial-gradient(760px 380px at 92% 4%,rgba(56,132,255,.10) 0%,transparent 62%);pointer-events:none}
.se-sphero__inner{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,1fr);gap:clamp(26px,3.4vw,54px);align-items:center;padding-block:clamp(34px,4.2vw,60px) clamp(40px,4.8vw,70px)}

.se-sphero__title{margin:0 0 .7rem;max-width:20ch}
.se-sphero__tagline{font-family:var(--se-font-head);font-weight:700;color:var(--se-navy);margin:0 0 .5rem}
.se-sphero__lead{font-size:1.0625rem;line-height:1.66;color:var(--se-ink);max-width:58ch;margin:0 0 1.1rem}
.se-sphero__lead p{margin:0 0 .9em}
.se-sphero__lead p:last-child{margin-bottom:0}

.se-sphero__points{list-style:none;margin:0 0 1.4rem;padding:0;display:flex;flex-wrap:wrap;gap:8px 20px}
.se-sphero__points li{display:inline-flex;align-items:center;gap:7px;font-family:var(--se-font-head);font-size:.875rem;font-weight:600;color:var(--se-navy)}
.se-sphero__points .se-icon{flex:none;padding:2px;border-radius:50%;color:var(--se-orange);background:color-mix(in srgb,var(--se-orange) 12%,transparent)}

.se-sphero__actions{display:flex;flex-wrap:wrap;gap:12px}
.se-sphero__media{min-width:0}

/*
   Approved photography in the hero.

   The composition the approved mockups use is the platform mark sitting on the
   device shot, so the mark is a badge anchored to the lower-left of the
   photograph rather than a separate decorative element. Intrinsic width and
   height are emitted by WordPress from the attachment metadata, so the image
   reserves its space and does not shift the hero while it loads.
*/
/*
   The hero band: a row of the page's own photographs, each at the size it was
   delivered at.

   A single photograph was stretched to the full hero column, which for a 192px
   portrait source is a 2.9x upscale and reads as a soft thumbnail. The band
   fills the same space with two or three photographs instead, none of them
   enlarged, and the row is capped at the width its own sources add up to so the
   photographs sit at 1:1 with the files in the Media Library.
*/
.se-sphero__band{
  display:grid;
  gap:12px;
  /*
   * The band is capped at the width of the column it sits in, and at the width
   * its own photographs add up to, whichever is smaller.
   *
   * Without the first cap, three 384px landscape photographs are 1152px wide in
   * a media column of about 589px: the grid could not shrink them because each
   * cell carries an explicit source width, so the row ran 96px past the viewport
   * at 1440. The page still did not scroll sideways — the body clips overflow —
   * which is exactly why this had to be measured rather than assumed. A clipped
   * overflow is invisible in a screenshot and unreachable for a keyboard user.
   */
  max-width:min(100%, calc(var(--se-photo-w,100%) + (var(--se-photo-n,1) - 1) * 12px));
  justify-content:start;
}
.se-sphero__band--2{grid-template-columns:repeat(2,minmax(0,1fr))}
.se-sphero__band--3{grid-template-columns:repeat(3,minmax(0,1fr))}

.se-sphero__cell{
  position:relative;margin:0;overflow:hidden;
  border-radius:var(--se-radius);
  background:var(--se-blue-soft);
  aspect-ratio:var(--se-cell-ratio,4/3);
  /*
   * min-width:0 lets the cell shrink below its source width when the column is
   * narrower than the photographs, which is what keeps the band inside its
   * column. A fixed width here is what pushed the row off the page.
   */
  min-width:0;width:100%;
  max-width:var(--se-cell-w,100%);
}
.se-sphero__image{display:block;width:100%;height:100%;object-fit:cover;object-position:center}
.se-sphero__mark{
  position:absolute;left:12px;bottom:12px;display:inline-flex;align-items:center;justify-content:center;
  width:52px;height:52px;padding:8px;border-radius:12px;background:#fff;
  box-shadow:0 6px 20px rgba(6,20,84,.18);
}
.se-sphero__markimg{display:block;width:100%;height:auto}

/* The approved "Technologies we work with" logo grid. */
.se-sp-marks{
  list-style:none;margin:22px 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:12px;
}
.se-sp-marks__item{
  display:inline-flex;align-items:center;justify-content:center;
  width:74px;height:74px;padding:14px;border-radius:14px;
  background:#fff;border:1px solid var(--se-line-soft);box-shadow:var(--se-shadow-sm);
}
.se-sp-marks__img{display:block;width:100%;height:auto}

/* Centered hero variant: the media sits under the copy, full width. */
.se-sphero--centered .se-sphero__inner{grid-template-columns:minmax(0,1fr);text-align:center}
.se-sphero--centered .se-sphero__content{max-width:70ch;margin-inline:auto}
.se-sphero--centered .se-sphero__title{max-width:26ch;margin-inline:auto}
.se-sphero--centered .se-sphero__lead{margin-inline:auto}
.se-sphero--centered .se-sphero__points,.se-sphero--centered .se-sphero__actions{justify-content:center}
.se-sphero--centered .se-sphero__media{max-width:960px;margin-inline:auto;width:100%}

/* --------------------------------------------------------------------------
   2. Scenes
   -------------------------------------------------------------------------- */
.se-scene-wrap{min-width:0}
.se-scene{display:block;width:100%;height:auto;border-radius:var(--se-radius);box-shadow:var(--se-shadow-sm)}
.se-scene-wrap--hero .se-scene{border-radius:var(--se-radius-lg);box-shadow:var(--se-shadow-lg)}

/* --------------------------------------------------------------------------
   3. Shared section frame
   -------------------------------------------------------------------------- */
.se-sp-prose{max-width:72ch}
.se-sp-prose p{margin:0 0 .9em}
.se-sp-prose p:last-child{margin-bottom:0}
.se-sp-prose h3{font-size:1.125rem;margin:1.6em 0 .5em}
.se-sp-prose h4{font-size:1rem;margin:1.4em 0 .4em}

.se-sp__intro{max-width:70ch;margin:0 0 clamp(20px,2.4vw,32px)}
.se-sp__intro p{margin:0 0 .8em}
.se-sp__intro p:last-child{margin-bottom:0}

/*
   Reading width, applied to the prose rather than to the container.

   .se-sp__narrow used to cap the .se-container itself at 820px, which centred a
   narrower box inside the 1280px container and pulled the left edge 230px inwards
   on every page that used it. Two sections on all 72 pages therefore started
   where the other sections did not. The container is now left alone and only the
   text column inside it is held to a comfortable measure, so the section keeps
   the site's left and right edges while the words stay readable.
*/
.se-sp__narrow>.se-prose,
.se-sp__narrow>.se-sp__intro,
.se-sp__narrow>.se-sp-intro__prose{max-width:74ch}

.se-sp__grid{display:grid;gap:clamp(24px,3vw,44px);align-items:center}
.se-sp__grid--split{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr)}
.se-sp__grid--intro{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:start}
.se-sp__grid--aside{grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr);align-items:start}
.se-sp__grid--flow{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);align-items:start}
.se-sp__grid--audit{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);align-items:start}
.se-sp__lead{min-width:0}
.se-sp__media{min-width:0}
.se-sp__media--narrow .se-scene-wrap{max-width:520px}

/* A split whose media comes first on wide screens. */
@media (min-width:1024px){
  .se-sp--flip .se-sp__grid{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr)}
  .se-sp--flip .se-sp__media{order:-1}
  .se-sp--layers .se-sp__media{order:2}
}

/* --------------------------------------------------------------------------
   4. Key list
   -------------------------------------------------------------------------- */
.se-sp-keylist{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.se-sp-keylist__item{display:flex;align-items:flex-start;gap:11px;min-width:0}
.se-sp-keylist__icon{flex:none;width:28px;height:28px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--se-orange) 12%,white);color:var(--se-orange-ink)}
.se-sp-keylist__body{min-width:0;display:flex;flex-direction:column}
.se-sp-keylist__label{font-family:var(--se-font-head);font-size:.9375rem;font-weight:700;color:var(--se-navy);line-height:1.35}
.se-sp-keylist__text{font-size:.875rem;line-height:1.58;color:var(--se-ink-soft);margin-top:2px}

.se-keylist--grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 22px}

/* --------------------------------------------------------------------------
   5. Cards
   -------------------------------------------------------------------------- */
.se-sp-cards{list-style:none;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;gap:16px}
.se-sp-cards--4{grid-template-columns:repeat(4,minmax(0,1fr))}
.se-sp-cards--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-cards--2{grid-template-columns:repeat(2,minmax(0,1fr))}

.se-sp-card{position:relative;display:flex;flex-direction:column;gap:8px;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:18px;box-shadow:var(--se-shadow-sm);transition:transform .2s var(--se-ease),box-shadow .2s var(--se-ease),border-color .2s var(--se-ease)}
.se-sp-card:hover{transform:translateY(-3px);box-shadow:var(--se-shadow);border-color:color-mix(in srgb,var(--se-orange) 32%,var(--se-line))}
.se-sp-card__icon{flex:none;width:40px;height:40px;border-radius:11px;display:inline-flex;align-items:center;justify-content:center;background:var(--se-blue-soft);color:var(--se-orange-ink)}
.se-sp-card__title{font-family:var(--se-font-head);font-size:1rem;font-weight:800;color:var(--se-navy);line-height:1.32;margin:0}
.se-sp-card__title a{color:inherit;text-decoration:none}
.se-sp-card__title a:hover{color:var(--se-orange-ink)}
.se-sp-card__text{font-size:.875rem;line-height:1.6;color:var(--se-ink-soft);margin:0;flex:1 1 auto}
.se-sp-card__link{align-self:flex-start;margin-top:2px;display:inline-flex;align-items:center;gap:6px;width:30px;height:30px;border-radius:50%;color:var(--se-navy);background:var(--se-mist);text-decoration:none;justify-content:center;transition:background-color .18s var(--se-ease),color .18s var(--se-ease)}
.se-sp-card__link:hover{background:var(--se-orange);color:#fff}

/*
   A card that already carries a description does not also need an arrow.

   The card title is the link, so the round arrow below it was a second control
   to the same destination, and on a grid of seven or eight it read as a column
   of buttons. It is kept only where the card is title-and-arrow with no
   description, where it is the sole affordance. Cards now carry a real
   description, so most of these disappear.
*/
.se-sp-card:has(.se-sp-card__text) .se-sp-card__link{
  position:absolute;top:14px;right:14px;margin-top:0;width:28px;height:28px;
}
.se-sp-card{position:relative}
.se-sp-card:has(.se-sp-card__text) .se-sp-card__title{padding-right:38px}

/*
   No description means no room for a corner arrow, so the pill treatment
   returns at one column where the link needs to read as a labelled control.
*/
@media (max-width:640px){
  .se-sp-card:has(.se-sp-card__text) .se-sp-card__link{
    position:static;margin-top:4px;width:auto;height:auto;border-radius:var(--se-radius-pill);
    padding:7px 14px;background:var(--se-mist);font-family:var(--se-font-head);font-size:.8125rem;font-weight:700;
  }
  .se-sp-card:has(.se-sp-card__text) .se-sp-card__title{padding-right:0}
}

/* --------------------------------------------------------------------------
   6. Intro / overview
   -------------------------------------------------------------------------- */
.se-sp-intro__prose{font-size:1.0625rem;line-height:1.7}
.se-sp-intro__prose p{margin:0 0 1em}
.se-sp-intro__prose p:last-child{margin-bottom:0}
.se-sp-intro__more{margin-top:1.6rem;padding-top:1.6rem;border-top:1px solid var(--se-line-soft)}
.se-sp-intro__more p{margin:0 0 .9em}

/* --------------------------------------------------------------------------
   7. Groups
   -------------------------------------------------------------------------- */
.se-sp-groups{display:grid;gap:clamp(20px,2.4vw,32px);margin-top:clamp(20px,2.4vw,32px)}
.se-sp-groups--2{grid-template-columns:repeat(2,minmax(0,1fr))}
.se-sp-groups--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-group{min-width:0;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:20px;box-shadow:var(--se-shadow-sm)}
.se-sp-group__title{font-family:var(--se-font-head);font-size:1.0625rem;font-weight:800;color:var(--se-navy);line-height:1.3;margin:0 0 14px;padding-bottom:10px;border-bottom:2px solid color-mix(in srgb,var(--se-orange) 30%,transparent)}

/* --------------------------------------------------------------------------
   8. Modules
   -------------------------------------------------------------------------- */
.se-sp-modules{list-style:none;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.se-sp-module{position:relative;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:20px 20px 22px;box-shadow:var(--se-shadow-sm);min-width:0}
.se-sp-module__num{position:absolute;top:16px;right:18px;font-family:var(--se-font-head);font-size:1.5rem;font-weight:800;color:color-mix(in srgb,var(--se-orange) 26%,transparent);line-height:1}
.se-sp-module__title{font-family:var(--se-font-head);font-size:1rem;font-weight:800;color:var(--se-navy);line-height:1.32;margin:0 0 7px;padding-right:34px}
.se-sp-module__text{font-size:.875rem;line-height:1.6;color:var(--se-ink-soft);margin:0}

/* --------------------------------------------------------------------------
   9. Process steps
   -------------------------------------------------------------------------- */
.se-sp-steps{list-style:none;counter-reset:spstep;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;gap:14px}
.se-sp-steps--7{grid-template-columns:repeat(4,minmax(0,1fr))}
.se-sp-steps--6{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-steps--5{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-steps--4{grid-template-columns:repeat(2,minmax(0,1fr))}
.se-sp-steps--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-step{position:relative;display:flex;align-items:flex-start;gap:12px;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:18px 18px 20px;box-shadow:var(--se-shadow-sm);min-width:0}
.se-sp-step__num{flex:none;width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:linear-gradient(140deg,var(--se-navy) 0%,var(--se-navy-700) 100%);color:#fff;font-family:var(--se-font-head);font-size:.9375rem;font-weight:800;line-height:1}
.se-sp-step__body{display:flex;flex-direction:column;min-width:0}
.se-sp-step__title{font-family:var(--se-font-head);font-size:.9375rem;font-weight:800;color:var(--se-navy);line-height:1.35}
.se-sp-step__text{font-size:.8125rem;line-height:1.55;color:var(--se-ink-soft);margin-top:3px}

/* --------------------------------------------------------------------------
   10. Flow
   -------------------------------------------------------------------------- */
.se-sp-flow{list-style:none;margin:0;padding:0;display:grid;gap:0;min-width:0}
.se-sp-flow__step{position:relative;display:flex;align-items:flex-start;gap:14px;padding:0 0 20px}
.se-sp-flow__step:last-child{padding-bottom:0}
/* The connector between steps, drawn with CSS so it is not an image. */
.se-sp-flow__step:not(:last-child)::before{content:'';position:absolute;left:16px;top:34px;bottom:0;width:2px;background:linear-gradient(180deg,color-mix(in srgb,var(--se-orange) 40%,transparent) 0%,var(--se-line) 100%)}
.se-sp-flow__num{flex:none;position:relative;z-index:1;width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:#fff;border:2px solid color-mix(in srgb,var(--se-orange) 46%,var(--se-line));color:var(--se-orange-ink);font-family:var(--se-font-head);font-size:.875rem;font-weight:800;line-height:1}
.se-sp-flow__body{display:flex;flex-direction:column;min-width:0;padding-top:2px}
.se-sp-flow__label{font-family:var(--se-font-head);font-size:.9375rem;font-weight:800;color:var(--se-navy);line-height:1.35}
.se-sp-flow__text{font-size:.8125rem;line-height:1.55;color:var(--se-ink-soft);margin-top:3px}

/* --------------------------------------------------------------------------
   11. Notes (architecture, anatomy, model, research, layers)
   -------------------------------------------------------------------------- */
.se-sp-notes{list-style:none;counter-reset:spnote;margin:clamp(18px,2.2vw,26px) 0 0;padding:0;display:grid;gap:12px}
.se-sp-note{position:relative;display:flex;align-items:flex-start;gap:12px;min-width:0;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius-sm);padding:14px 16px}
.se-sp-note__num{flex:none;width:26px;height:26px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--se-blue-soft);color:var(--se-orange-ink);font-family:var(--se-font-head);font-size:.8125rem;font-weight:800;line-height:1}
.se-sp-note__body{display:flex;flex-direction:column;min-width:0}
.se-sp-note__label{font-family:var(--se-font-head);font-size:.9375rem;font-weight:800;color:var(--se-navy);line-height:1.35}
.se-sp-note__text{font-size:.8125rem;line-height:1.55;color:var(--se-ink-soft);margin-top:3px}

/* --------------------------------------------------------------------------
   12. Triad
   -------------------------------------------------------------------------- */
.se-sp-triad{list-style:none;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;gap:18px}
.se-sp-triad--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp-triad--4{grid-template-columns:repeat(4,minmax(0,1fr))}
.se-sp-triad__item{display:flex;flex-direction:column;gap:10px;min-width:0}
.se-sp-triad__scene{background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:10px;box-shadow:var(--se-shadow-sm)}
.se-sp-triad__title{font-family:var(--se-font-head);font-size:1rem;font-weight:800;color:var(--se-navy);line-height:1.32;margin:0}
.se-sp-triad__text{font-size:.875rem;line-height:1.6;color:var(--se-ink-soft);margin:0}

/* --------------------------------------------------------------------------
   13. Readiness
   -------------------------------------------------------------------------- */
.se-sp-readiness{list-style:none;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.se-sp-readiness__item{position:relative;min-width:0;background:#fff;border:1px solid var(--se-line);border-top:3px solid color-mix(in srgb,var(--se-orange) 55%,transparent);border-radius:var(--se-radius);padding:20px;box-shadow:var(--se-shadow-sm)}
.se-sp-readiness__num{font-family:var(--se-font-head);font-size:.8125rem;font-weight:800;letter-spacing:.08em;color:var(--se-orange-ink);display:block;margin-bottom:8px}
.se-sp-readiness__title{font-family:var(--se-font-head);font-size:1.0625rem;font-weight:800;color:var(--se-navy);line-height:1.3;margin:0 0 7px}
.se-sp-readiness__text{font-size:.875rem;line-height:1.6;color:var(--se-ink-soft);margin:0}

/* --------------------------------------------------------------------------
   14. Diagnostic signs
   -------------------------------------------------------------------------- */
.se-sp-signs{list-style:none;margin:clamp(20px,2.4vw,32px) 0 0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.se-sp-sign{display:flex;align-items:flex-start;gap:13px;min-width:0;background:#fff;border:1px solid var(--se-line);border-radius:var(--se-radius);padding:18px}
.se-sp-sign__num{flex:none;width:32px;height:32px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--se-orange) 12%,white);color:var(--se-orange-ink);font-family:var(--se-font-head);font-size:.875rem;font-weight:800;line-height:1}
.se-sp-sign__body{display:flex;flex-direction:column;min-width:0}
.se-sp-sign__label{font-family:var(--se-font-head);font-size:.9375rem;font-weight:800;color:var(--se-navy);line-height:1.35}
.se-sp-sign__text{font-size:.8125rem;line-height:1.55;color:var(--se-ink-soft);margin-top:3px}
.se-sp-sign__note{display:flex;align-items:flex-start;gap:9px;margin:clamp(18px,2.2vw,26px) 0 0;padding:16px 18px;background:#fff;border-left:3px solid var(--se-orange);border-radius:0 var(--se-radius-sm) var(--se-radius-sm) 0;font-size:.875rem;line-height:1.6;color:var(--se-ink)}
.se-sp-sign__note .se-icon{flex:none;margin-top:3px;color:var(--se-orange-ink)}

/* --------------------------------------------------------------------------
   15. Aside panel
   -------------------------------------------------------------------------- */
.se-sp-aside{background:linear-gradient(150deg,var(--se-navy) 0%,#0d3a7d 100%);color:#fff;border-radius:var(--se-radius);padding:24px;display:flex;flex-direction:column;gap:12px;align-items:flex-start;box-shadow:var(--se-shadow)}
.se-sp-aside__icon{width:44px;height:44px;border-radius:12px;display:inline-flex;align-items:center;justify-content:center;background:rgba(255,255,255,.12);color:#ffb27a}
.se-sp-aside__title{font-family:var(--se-font-head);font-size:1.125rem;font-weight:800;color:#fff;line-height:1.3;margin:0}
.se-sp-aside__text{font-size:.875rem;line-height:1.65;margin:0;opacity:.92}
.se-sp-aside .se-btn--outline{color:#fff;border-color:rgba(255,255,255,.65)}
.se-sp-aside .se-btn--outline:hover{background:#fff;color:var(--se-navy)}

/* --------------------------------------------------------------------------
   16. Tables (matrix, compare)
   -------------------------------------------------------------------------- */
/*
   Editorial replacement for the former capability table.

   The subject is a heading and its explanation is prose under it, so the section
   reads as written material rather than as a spec sheet. A rule between rows
   keeps the grouping legible without a grid, and the whole thing reflows to one
   column on a phone with no horizontal scroll container.
*/
.se-sp-matrix{margin-top:clamp(18px,2vw,28px);border-top:1px solid var(--se-line)}
.se-sp-matrix__row{
  display:grid;grid-template-columns:minmax(180px,.34fr) minmax(0,1fr);
  gap:8px clamp(24px,3vw,48px);padding:clamp(18px,1.8vw,24px) 0;
  border-bottom:1px solid var(--se-line-soft);align-items:baseline;
}
.se-sp-matrix__label{
  margin:0;font-family:var(--se-font-head);font-size:1.0625rem;font-weight:800;
  color:var(--se-navy);line-height:1.35;letter-spacing:-.005em;
}
.se-sp-matrix__body{min-width:0}
.se-sp-matrix__text{margin:0;color:var(--se-ink-soft);font-size:1rem;line-height:1.68;max-width:74ch}
.se-sp-matrix__list{margin:0;padding:0;list-style:none;display:grid;gap:8px}
.se-sp-matrix__list li{
  position:relative;padding-left:20px;color:var(--se-ink-soft);
  font-size:1rem;line-height:1.62;max-width:74ch;
}
.se-sp-matrix__list li::before{
  content:"";position:absolute;left:2px;top:.62em;width:6px;height:6px;
  border-radius:50%;background:var(--se-orange);
}

/*
   Editorial replacement for the former comparison table.

   Two headed columns rather than a grid. On a wide screen the aspects sit in a
   left column and each option occupies its own column, so the reader compares
   downward. On a phone each option becomes a labelled block, which is how the
   decision is actually made, with no sideways scrolling.
*/
.se-sp-compare{
  margin-top:clamp(18px,2vw,28px);
  /*
     One column per option, and the count is written by the template.

     The rule used to read

         grid-template-columns:minmax(160px,.34fr) repeat(auto-fit,minmax(0,1fr));

     repeat(auto-fit, ...) is only valid as the whole track list. Mixed in after
     another track, the browser resolved the repeat to fill every remaining
     1fr-sized slot it could, which produced twenty-five tracks where three were
     meant: a 160px aspect column and twenty-four columns of about 24px each. The
     two option columns collapsed to 24px wide, the text wrapped to one word per
     line, and rows overlapped each other. Every page carrying a compare block
     was broken at every width, on desktop as well as mobile.

     --se-compare-cols is set to the real number of options by
     smartedge_sp_block_compare(), so a two-option and a three-option comparison
     each get the right track count.
  */
  display:grid;
  grid-template-columns:minmax(150px,.34fr) repeat(var(--se-compare-cols,2),minmax(0,1fr));
  gap:0 clamp(24px,3vw,48px);
}
.se-sp-compare__head{
  display:contents;
}
/*
   The corner cell holds the row-label column.

   It is an empty element, but it must still occupy a grid cell. With
   display:none it is taken out of the flow, so the two option headings shifted
   one track left into the row-label column, every aspect label shifted into the
   first option column, and the values landed a column further right than the
   headings they belong to. Measured before this fix at 1440px: the label track
   was 166px and the first option track was 490px, with the aspects sitting in
   the 490px track and the headings in the 166px one — the comparison read
   backwards.

   So it stays in the grid, empty and invisible, which is what it is for.
*/
.se-sp-compare__corner{
  visibility:hidden;
  padding:0;
  margin:0;
}
.se-sp-compare__col{
  margin:0;padding:0 0 14px;border-bottom:2px solid var(--se-navy);
  font-family:var(--se-font-head);font-size:1.0625rem;font-weight:800;color:var(--se-navy);
}
.se-sp-compare__row{
  display:contents;
}
.se-sp-compare__aspect,.se-sp-compare__value{
  margin:0;padding:16px 0;border-bottom:1px solid var(--se-line-soft);
  line-height:1.62;font-size:.9688rem;
}
.se-sp-compare__aspect{
  font-family:var(--se-font-head);font-weight:700;color:var(--se-navy);
}
.se-sp-compare__value{color:var(--se-ink-soft);max-width:44ch}

/*
   Narrow screens: each aspect becomes a small block with its options stacked
   under it, rather than one long list where the reader loses the question.

   The block used to flatten to display:block, which produced a wall of
   question-then-answer-then-answer with nothing marking where one aspect ended
   and the next began. Grouping each aspect with its own options, and repeating
   the option name inside the group on the narrowest screens, makes the block
   readable as a series of labelled comparisons. No data is dropped: the option
   headings are still printed once, in order, above the first aspect.
*/
@media (max-width:820px){
  .se-sp-matrix__row{grid-template-columns:minmax(0,1fr);gap:8px}
  .se-sp-compare{grid-template-columns:minmax(0,1fr);gap:0}
  .se-sp-compare__head{display:block;margin-bottom:4px}
  /*
     The corner cell is the first child of the head block. As a grid cell it had
     to stay in the flow so the option headings lined up with their columns; as a
     block-level child it is just an empty element taking a line of height, so it
     is taken out of the flow here.
  */
  .se-sp-compare__corner{display:none}
  .se-sp-compare__col{padding-bottom:8px;border-bottom:1px solid var(--se-line-soft)}
  .se-sp-compare__col+.se-sp-compare__col{margin-top:18px}
  .se-sp-compare__row{
    display:block;
    margin-top:20px;
    padding:16px 0;
    border-bottom:1px solid var(--se-line-soft);
  }
  .se-sp-compare__aspect{
    margin:0 0 10px;
    padding:0;
    border-bottom:0;
    font-size:1rem;
  }
  .se-sp-compare__value{padding:0 0 10px;max-width:none}
  .se-sp-compare__value:last-child{padding-bottom:0}
}

/*
   Below 560px the option names are repeated against each value.

   The wide layout puts the two option headings in one row at the top and relies
   on the reader holding the association as they scan down. Stacked, that
   association is gone, so each value carries its own label — read by a screen
   reader and printed in a data attribute rather than duplicated visibly, so the
   page shows the same words twice on a phone and once everywhere else.
*/
@media (max-width:560px){
  .se-sp-compare__value{
    padding-left:14px;
    border-left:2px solid var(--se-line-soft);
  }
  .se-sp-compare__value::before{
    content:attr(data-option) ' — ';
    font-family:var(--se-font-head);
    font-weight:700;
    color:var(--se-navy);
  }
}

.se-sp-tablewrap{margin-top:clamp(20px,2.4vw,32px);overflow-x:auto;border:1px solid var(--se-line);border-radius:var(--se-radius);background:#fff}
.se-sp-table{width:100%;border-collapse:collapse;font-size:.875rem;min-width:560px}
.se-sp-table th,.se-sp-table td{padding:14px 16px;text-align:left;vertical-align:top;border-bottom:1px solid var(--se-line-soft);line-height:1.55}
.se-sp-table thead th{font-family:var(--se-font-head);font-size:.8125rem;font-weight:800;color:var(--se-navy);letter-spacing:.02em;background:var(--se-mist);white-space:nowrap}
.se-sp-table tbody th{font-family:var(--se-font-head);font-weight:700;color:var(--se-navy);width:1%;white-space:nowrap;background:var(--se-blue-soft)}
.se-sp-table tbody tr:last-child th,.se-sp-table tbody tr:last-child td{border-bottom:0}
.se-sp-table--compare tbody th{background:#fff}
.se-sp-table--compare thead th:not(:first-child){background:color-mix(in srgb,var(--se-orange) 8%,var(--se-mist))}
.se-sp-tablewrap:focus-visible{outline:3px solid var(--se-orange);outline-offset:2px}

.se-sp-tailkeylist{margin-top:clamp(24px,2.8vw,36px);padding-top:clamp(20px,2.4vw,28px);border-top:1px solid var(--se-line-soft)}
.se-sp-tailkeylist__title{font-family:var(--se-font-head);font-size:1.125rem;font-weight:800;color:var(--se-navy);margin:0 0 14px}

/* ---------------------------------------- Section heading and its intro paragraph */

/*
   The heading and the paragraph that introduces the section share one row.

   Why
   ---
   Across the service pages the same shape recurred: a heading block of 460px and
   an intro paragraph of about 700px, both left-aligned, above a card grid or a
   list that then spanned the full 1232px. The top-right quadrant of every one of
   those sections was empty — measured at 130px to 400px of it on sixty-odd pages
   — and the section read as if it had been laid out for a narrower page and then
   stretched.

   Putting the two side by side fills that quadrant with copy that was already
   written for that page. Nothing is invented, nothing moves between sections, and
   the paragraph keeps a measure of about 62 characters.

   Why it is scoped to this exact shape
   -----------------------------------
   The rule needs a heading as the first child and the intro paragraph as the
   second, with the section's own content after them. That shape was verified
   across all 72 service URLs before the rule was written: 24 distinct child
   sequences, and in every one of them the heading is first, the intro is second
   when it exists at all, and the section's own content follows.

   Three kinds of container are deliberately left out:

     - one that already is a grid (.se-sp__grid--split, --aside, --intro): those
       are two-column sections with their own balance and must not be re-gridded;
     - .se-sp--tech__inner, a centred composition by design, which has the
       smallest right-side gap of any section;
     - .se-sp__narrow, the FAQ band, whose heading is centred above the questions.

   A section with a heading and no intro paragraph is left out too: there the
   heading would sit alone in the first column with the second column empty, which
   is the fault this rule exists to remove rather than create.
*/
@media (min-width:1024px){
  section > .se-container:has(> .se-sh:first-child):has(> .se-sp__intro:nth-child(2)) {
    display:grid;
    grid-template-columns:minmax(0,0.92fr) minmax(0,1.08fr);
    column-gap:clamp(28px,3.4vw,60px);
    align-items:end;
  }
  /* The heading in column one, the paragraph in column two, and everything after
     them — the card grid, the list, the diagram — across the full width, in the
     order the block renderer wrote it. */
  section > .se-container:has(> .se-sh:first-child):has(> .se-sp__intro:nth-child(2)) > .se-sh {
    grid-column:1;
    grid-row:1;
  }
  section > .se-container:has(> .se-sh:first-child):has(> .se-sp__intro:nth-child(2)) > .se-sp__intro {
    grid-column:2;
    grid-row:1;
    max-width:none;
  }
  section > .se-container:has(> .se-sh:first-child):has(> .se-sp__intro:nth-child(2)) > :not(.se-sh):not(.se-sp__intro) {
    grid-column:1 / -1;
  }
}

/* Below 1024px it is one column again, and the paragraph keeps a reading measure
   instead of running the full width of a tablet. */
@media (max-width:1023px){
  .se-sp__intro{max-width:70ch}
}

/* --------------------------------------------------------------------------
   17. Why grid / promo / chips
   -------------------------------------------------------------------------- */
.se-sp-why{grid-template-columns:repeat(3,minmax(0,1fr))}
.se-sp--promo{padding-block:0}
.se-sp__promo{margin-block:clamp(8px,1.4vw,18px)}
.se-sp-chips{justify-content:center;max-width:980px;margin-inline:auto}
.se-sp-chips li{background:#fff;border:1px solid var(--se-line);color:var(--se-navy);font-weight:700}

/* --------------------------------------------------------------------------
   18. Work
   -------------------------------------------------------------------------- */
.se-sp-work{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:clamp(20px,2.4vw,32px)}
.se-sp-work__more{margin:clamp(22px,2.6vw,34px) 0 0}

/* --------------------------------------------------------------------------
   19. CTA
   -------------------------------------------------------------------------- */
.se-sp-cta .se-container{position:relative;z-index:1}

/* --------------------------------------------------------------------------
   20. Responsive
   -------------------------------------------------------------------------- */
@media (max-width:1180px){
  .se-sp-cards--4{grid-template-columns:repeat(3,minmax(0,1fr))}
  .se-sp-readiness{grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media (max-width:1023px){
  .se-sphero__inner{grid-template-columns:minmax(0,1fr);gap:26px}
  .se-sphero__title{max-width:24ch}
  .se-sp__grid--split,
  .se-sp__grid--intro,
  .se-sp__grid--aside,
  .se-sp__grid--flow,
  .se-sp__grid--audit{grid-template-columns:minmax(0,1fr)}
  .se-sp__media{order:-1}
  .se-sp__media--narrow .se-scene-wrap{max-width:none}
  .se-sp-modules{grid-template-columns:repeat(2,minmax(0,1fr))}
  .se-sp-triad--4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .se-sp-groups--3{grid-template-columns:minmax(0,1fr)}
  .se-sp-steps--7,.se-sp-steps--6,.se-sp-steps--5,.se-sp-steps--3{grid-template-columns:repeat(2,minmax(0,1fr))}
  .se-keylist--grid{grid-template-columns:minmax(0,1fr)}
}

@media (max-width:820px){
  .se-sp-cards--4,.se-sp-cards--3,.se-sp-cards--2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .se-sp-work{grid-template-columns:repeat(2,minmax(0,1fr))}
  .se-sp-signs{grid-template-columns:minmax(0,1fr)}
}

@media (max-width:640px){
  .se-sp-modules,
  .se-sp-readiness,
  .se-sp-triad--3,
  .se-sp-triad--4,
  .se-sp-groups--2,
  .se-sp-work,
  .se-sp-steps--7,
  .se-sp-steps--6,
  .se-sp-steps--5,
  .se-sp-steps--4,
  .se-sp-steps--3{grid-template-columns:minmax(0,1fr)}
  .se-sp-cards--4,.se-sp-cards--3,.se-sp-cards--2{grid-template-columns:minmax(0,1fr)}
  .se-sphero__lead{font-size:1rem}
  .se-sphero__points{gap:7px 14px}
  .se-sphero__mark{width:52px;height:52px;padding:8px;left:12px;bottom:12px}
  .se-sp-marks__item{width:60px;height:60px;padding:11px}
  .se-sp__narrow{max-width:none}
  /* At one column the card link stays visible as a labelled row rather than a
     bare arrow, so the destination is obvious on a touch device. */
  .se-sp-card__link{width:auto;height:auto;border-radius:var(--se-radius-pill);padding:7px 14px;background:var(--se-mist);font-family:var(--se-font-head);font-size:.8125rem;font-weight:700}
  /*
   * The card link carries a screen-reader-only "Read about <topic>" label, which is
   * promoted to visible text on a phone where the arrow icon alone is not a clear
   * affordance. It is allowed to wrap here.
   *
   * It was nowrap, which is what pushed two cards 13px past the right edge of a
   * 390px viewport: "Read about Generative Engine Optimization" is 41 characters
   * and does not fit on one line inside a 354px column. The page did not scroll
   * sideways because the body clips overflow, so this was invisible without
   * measuring the elements.
   */
  .se-sp-card__link .screen-reader-text{
    position:static!important;width:auto;height:auto;
    clip:auto;clip-path:none;overflow:visible;
    white-space:normal;margin:0;
  }
  .se-sp-card__link{max-width:100%}
}

@media (max-width:420px){
  .se-sp-table{font-size:.8125rem}
  .se-sp-table th,.se-sp-table td{padding:11px 12px}
}

@media print{
  .se-sphero__media,.se-sp__media,.se-sp-triad__scene{display:none}
  .se-sp__grid--split,.se-sp__grid--flow{grid-template-columns:minmax(0,1fr)}
}

/* --------------------------------------------------------------------------
   Section reveal

   Applied to the outer section elements only, and only once JavaScript has
   confirmed the visitor has not asked for reduced motion. The hidden state is
   set from JavaScript rather than declared here on purpose: if the script never
   runs, or the observer never fires, the content still has to be visible. A
   stylesheet that started every section at opacity 0 would leave an invisible
   page whenever anything went wrong, which is a far worse outcome than no
   animation at all.

   12px and half a second, so the page reads as settling rather than performing.
   -------------------------------------------------------------------------- */
.se-sp[data-se-reveal],
.se-sphero[data-se-reveal]{
  opacity:0;
  transform:translate3d(0,12px,0);
  transition:opacity .5s var(--se-ease),transform .5s var(--se-ease);
}
.se-sp[data-se-reveal].is-revealed,
.se-sphero[data-se-reveal].is-revealed{
  opacity:1;
  transform:none;
}

@media (prefers-reduced-motion:reduce){
  .se-sp[data-se-reveal],
  .se-sphero[data-se-reveal]{
    opacity:1;
    transform:none;
    transition:none;
  }
}

/* --------------------------------------------------------------------------
   Raster section visuals

   Replaces the former inline SVG scenes. A <figure> is used so the image is a
   real content image with alt text and intrinsic dimensions, which is what makes
   it replaceable and auditable; the intrinsic size also reserves the space, so
   a section does not shift while the picture loads.
   -------------------------------------------------------------------------- */
.se-spvis-wrap{margin:0;min-width:0}
.se-spvis{
  display:block;width:100%;height:auto;border-radius:var(--se-radius);
  background:var(--se-blue-soft);box-shadow:var(--se-shadow-sm);
}
.se-sphero__figure.se-scene-wrap--hero{
  overflow:hidden;border-radius:var(--se-radius-lg);box-shadow:var(--se-shadow-lg);
}
.se-sphero__figure .se-spvis{border-radius:0;box-shadow:none;background:none}

/* --------------------------------------------------------------------------
   Sideways service navigation

   Replaces the second card grid. On a service page the sibling services are
   navigation, not content, so they are rendered as a wrapped link list: no card
   chrome, no repeated blurb, and no second arrow link beside the title. The
   previous version reprinted each sibling's blurb and linked it twice, which
   repeated the same prose on every page of a category.
   -------------------------------------------------------------------------- */
.se-sp-cats__links{
  display:flex;flex-wrap:wrap;gap:10px 12px;
  max-width:840px;margin-inline:auto;padding:0;list-style:none;
}
.se-sp-cats__links-item{margin:0}
/*
 * A white pill with a hairline border rather than a tinted one. The section
 * background is --se-mist and the available blue tints are lighter still, so a
 * tinted pill on this background is invisible at any contrast that would still
 * pass the body-text check. The border is what makes the list read as a set of
 * targets rather than as loose text.
 */
.se-sp-cats__links a{
  display:inline-block;padding:9px 18px;border-radius:var(--se-radius-pill);
  background:#fff;border:1px solid var(--se-line);color:var(--se-navy);
  font-size:.9375rem;font-weight:600;line-height:1.35;
  text-decoration:none;
  transition:background-color .18s ease,border-color .18s ease,color .18s ease;
}
.se-sp-cats__links a:hover{
  background:var(--se-navy);border-color:var(--se-navy);color:#fff;
}
.se-sp-cats__links a:focus-visible{outline:3px solid var(--se-orange);outline-offset:2px}

/* --------------------------------------------------------------------------
   Technology band

   Centred as one block. The heading, the paragraph and the list of platform
   names are a single unit here, so left-aligning the heading while centring the
   chips left the top-right of every technology section permanently empty.
   The paragraph is given a reading width rather than running the full container.
   -------------------------------------------------------------------------- */
.se-sp--tech__inner{
  display:flex;flex-direction:column;align-items:center;text-align:center;
}
.se-sp--tech .se-sh{max-width:34ch}
.se-sp--tech .se-sh__title{text-wrap:balance}
.se-sp--tech__intro{
  max-width:68ch;margin-top:18px;
}
.se-sp--tech__intro p{margin:0 0 14px;text-align:center}
.se-sp--tech__chips{
  justify-content:center;max-width:1040px;margin-top:26px;
}

/*
 * With marks, the layout becomes two columns: the writing on the left, the logo
 * grid on the right. That is the only arrangement in which a mark has something
 * to balance against.
 */
.se-sp--tech--with-marks .se-sp--tech__inner{align-items:stretch;text-align:left}
.se-sp--tech--with-marks .se-sh{max-width:30ch}
.se-sp--tech--with-marks .se-sp__intro p{text-align:left}
.se-sp--tech--with-marks .se-sp__chips{
  justify-content:flex-start;max-width:none;
}
@media (min-width:1024px){
  .se-sp--tech--with-marks .se-sp--tech__inner{
    display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px 48px;align-items:start;
  }
  .se-sp--tech--with-marks .se-sp__chips{grid-column:1}
  .se-sp--tech--with-marks .se-sp-marks{grid-column:2;grid-row:1/span 2;max-width:260px}
}
@media (max-width:640px){
  .se-sp--tech .se-sh{max-width:none}
  .se-sp--tech__intro{max-width:none}
}

/* --------------------------------------------------------------------------
   Architecture block

   The diagram, the notes and the heading each take the full container. In a
   two-column split the notes column was taller than a wide, short diagram, so
   the image column carried a band of empty space beneath it on every page that
   used the block.
   -------------------------------------------------------------------------- */
.se-sp--architecture__figure{
  margin:26px auto 0;max-width:1080px;
}
.se-sp--architecture .se-sp__intro{max-width:74ch;margin-inline:auto}
.se-sp--architecture .se-sh{max-width:34ch;margin-inline:auto;text-align:center}

/*
 * Notes in columns. Six stacked rows under a full-width diagram reads as a wall,
 * so they are laid out side by side where there is room.
 */
.se-sp-notes--cols{
  margin-top:28px;display:grid;gap:16px 22px;
  grid-template-columns:repeat(2,minmax(0,1fr));
}
.se-sp-notes--cols.se-sp-notes--3{grid-template-columns:repeat(3,minmax(0,1fr))}
/*
 * The label sits above its description rather than beside it. Side by side in a
 * three-column grid the label column was about eighty pixels wide, so
 * "Catalogue and pricing" wrapped onto three lines beside a single line of
 * description.
 */
.se-sp-notes--cols .se-sp-note{
  display:flex;flex-direction:column;gap:5px;
  background:var(--se-white,#fff);border:1px solid var(--se-line);
  border-left:3px solid var(--se-blue);
  border-radius:var(--se-radius);padding:15px 17px;margin:0;
}
.se-sp-notes--cols .se-sp-note__label{
  display:block;font-size:.9375rem;font-weight:700;
  color:var(--se-navy);line-height:1.35;
}
.se-sp-notes--cols .se-sp-note__text{
  display:block;font-size:.9375rem;line-height:1.6;color:var(--se-ink-soft,#41506a);
}
@media (max-width:900px){
  .se-sp-notes--cols.se-sp-notes--3{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .se-sp-notes--cols,
  .se-sp-notes--cols.se-sp-notes--3{grid-template-columns:1fr}
}

/* --------------------------------------------------------------------------
   Section photography

   Mid-page visuals are photographs from the approved library rather than drawn
   diagrams, so a service page reads as an engineering practice rather than a
   wireframe document. Images are cropped with object-fit and a controlled
   aspect ratio so a photograph is never stretched to fill a column.
   -------------------------------------------------------------------------- */
.se-spphoto{
  margin:0;min-width:0;
  display:grid;
  gap:14px;
  /*
   * A row never exceeds the column it sits in, and its cells are laid out at the
   * width the photographs were delivered at.
   *
   * The renderer writes each cell's source width as --se-cell-w and the row's as
   * --se-photo-w, so the sizing comes from the actual file rather than from a
   * number guessed at a breakpoint. Cells at that width can only ever shrink,
   * never grow, which is what keeps the library from being enlarged.
   */
  max-width:100%;
}
/*
 * The number of cells decides the columns, and the count is written into the
 * class by the renderer, so the layout never has to guess at a breakpoint
 * whether a slot holds one photograph or three.
 */

/*
 * One photograph fills the column.
 *
 * A service page's media column is 464px at 1280px and 728px once the layout
 * stacks, and the photographs are 960px on the long edge, so a single picture
 * fills that column by scaling down and has width to spare. It takes the column
 * rather than sitting in it at its own size, because a 960px picture in a 464px
 * column at its natural size would overflow, and an auto-repeat track sized at
 * the source width does exactly that: the track is definite, it is wider than the
 * column, and the row runs past the edge of the page.
 *
 * min(100%, the source width) is the cap. Where a photograph is narrower than the
 * column it sits at its own width and centres, which is what stops a small source
 * being enlarged; where it is wider, which is every photograph on the site now,
 * 100% wins and it fills the column.
 */
.se-spphoto--1{grid-template-columns:minmax(0,1fr)}
.se-spphoto--1 .se-spphoto__cell{
  width:100%;
  max-width:min(100%,var(--se-cell-w,100%));
}

/*
 * Two or three photographs are laid out at the width they were delivered at, and
 * the row holds as many as fit in the column before wrapping to the next line.
 *
 * auto-fit at the source width rather than a fixed column count, because the two
 * batches want opposite compositions. Three 192px portraits come to 576px and
 * fill a media column in one line, which matches the copy height closely. Two
 * 384px landscapes in one line are only 213px tall, and beside a 393px copy
 * column that left 46% of the media column empty — the exact fault this work
 * exists to remove. At the source width they wrap onto two lines instead and the
 * row becomes 440px, which balances the copy column.
 *
 * The row is centred so a wrapped block reads as a deliberate composition rather
 * than as a column left hanging at one edge.
 */
.se-spphoto--2,
.se-spphoto--3{
  grid-template-columns:repeat(auto-fit,var(--se-cell-w,auto));
  justify-content:center;
}

/*
 * A cell holds the photograph at the size it was delivered at.
 *
 * A cell is capped at the width its source can actually fill, and the cap is
 * written per cell from the source ratio rather than assumed. The images are laid
 * out at their intrinsic size and allowed to shrink, never stretched: width:100%
 * with height:auto and object-fit:cover inside a box of the source's own ratio
 * means the browser scales the picture down when the column is narrow and never up
 * when it is wide.
 */
.se-spphoto__cell{
  margin:0;min-width:0;overflow:hidden;
  border-radius:var(--se-radius);
  background:var(--se-blue-soft);
  /* The source's own ratio, so the cell is the right shape before the file
     arrives and the row does not reflow as photographs load. */
  aspect-ratio:var(--se-cell-ratio,4/3);
  /*
   * The source's own width, so the cell never exceeds the photograph it holds.
   * The grid is sized to these, and the cap above stops the row being stretched
   * past them by a wider parent. A single photograph overrides this to take the
   * column, which is the rule immediately above.
   */
  width:var(--se-cell-w,auto);
}
.se-spphoto__img{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:center;
}

/*
 * A row never exceeds the width its own sources add up to, so a photograph is
 * not enlarged past the size it was delivered at. The cap is generous because it
 * only has to catch the pathological case; the grid columns above are what
 * actually control the width.
 */
.se-spphoto{max-width:100%}
.se-spphoto__img{max-width:100%}

/* The fallback panel, used only where the plan has no photograph. */
.se-spphoto--panel{
  aspect-ratio:16/10;display:flex;align-items:flex-end;
  padding:22px;background:var(--se-blue-soft);
}
.se-spphoto--panel .se-eyebrow{margin:0}

/* --------------------------------------------------------------------------
   Architecture section: photograph beside the notes, diagram beneath.

   Measured at 79% column imbalance before this layout, because the notes column
   was far taller than a wide, short diagram beside it.
   -------------------------------------------------------------------------- */
.se-sp--architecture__grid{
  display:grid;gap:30px 44px;margin-top:28px;align-items:stretch;
  grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
}
.se-sp--architecture__grid--full{grid-template-columns:1fr}
/*
 * The media wrapper is a plain block, not a flex or grid container.
 *
 * As a flex item the photograph sized itself from the image's intrinsic width
 * rather than from the column, so it rendered at the full viewport width inside
 * a 642px grid column and broke the layout it was meant to fill.
 */
.se-sp--architecture__media{min-width:0}
.se-sp--architecture__media .se-spphoto,
.se-sp--architecture__notes .se-spphoto{width:100%;max-width:100%}
.se-sp--architecture__notes{min-width:0;display:flex;flex-direction:column;justify-content:center}

.se-sp-notes--stack{
  margin:0;padding:0;list-style:none;
  display:flex;flex-direction:column;gap:14px;
}
.se-sp-notes--stack .se-sp-note{
  margin:0;padding:16px 18px;
  background:var(--se-white,#fff);
  border:1px solid var(--se-line);
  border-left:3px solid var(--se-blue);
  border-radius:var(--se-radius);
}
.se-sp-notes--stack .se-sp-note__label{
  display:block;margin-bottom:4px;
  font-size:.9375rem;font-weight:700;color:var(--se-navy);line-height:1.35;
}
.se-sp-notes--stack .se-sp-note__text{
  display:block;font-size:.9375rem;line-height:1.6;color:var(--se-ink-soft,#41506a);
}
.se-sp--architecture__figure{margin:30px auto 0;max-width:1080px}

@media (max-width:900px){
  .se-sp--architecture__grid{grid-template-columns:1fr;gap:24px}
  .se-sp--architecture__notes{justify-content:flex-start}
}

/*
 * No photograph may exceed its column. An image inside a grid or flex item is
 * sized by its intrinsic width unless it is explicitly constrained, which is how
 * a 1440px-wide picture ended up inside a 642px column.
 */
.se-spphoto{max-width:100%}
.se-spphoto__img{max-width:100%}

/* Full-width photographic band, with the notes in columns beneath it. */
.se-sp--architecture__figure--band{margin:30px auto 0;max-width:none}
.se-sp--architecture__figure--band .se-spphoto{aspect-ratio:21/9}
@media (max-width:760px){
  .se-sp--architecture__figure--band .se-spphoto{aspect-ratio:16/11}
}

/*
 * The diagram sits behind a disclosure rather than directly under the notes.
 *
 * It was previously an open full-width block, which pushed the real editorial
 * content a screen further down and left the section reading as a chart with some
 * text attached. Readers who want the structure can open it; readers who came
 * for the service see the photograph and the notes first.
 */
.se-sp-detail{
  margin:26px auto 0;max-width:1080px;
  border:1px solid var(--se-line);border-radius:var(--se-radius);
  background:var(--se-white,#fff);overflow:hidden;
}
.se-sp-detail__summary{
  cursor:pointer;list-style:none;
  padding:14px 18px;
  font-size:.9375rem;font-weight:600;color:var(--se-navy);
  display:flex;align-items:center;gap:10px;
}
.se-sp-detail__summary::-webkit-details-marker{display:none}
.se-sp-detail__summary::after{
  content:"";margin-left:auto;width:9px;height:9px;
  border-right:2px solid var(--se-navy);border-bottom:2px solid var(--se-navy);
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .18s ease;
}
.se-sp-detail[open] .se-sp-detail__summary::after{transform:rotate(-135deg) translate(-3px,-3px)}
.se-sp-detail__summary:hover{background:var(--se-blue-soft)}
.se-sp-detail__summary:focus-visible{outline:3px solid var(--se-orange);outline-offset:-3px}
.se-sp-detail__body{padding:0 18px 18px}

/* --------------------------------------------------------------------------
   Process section: steps beside the secondary photograph

   Previously a full-width numbered list with no visual support, which is the
   part of a service page a reader is most likely to skim past.
   -------------------------------------------------------------------------- */
.se-sp--process__grid{
  display:grid;gap:28px 40px;margin-top:26px;
  grid-template-columns:minmax(0,1fr) minmax(0,.62fr);
  align-items:center;
}
.se-sp--process__grid--full{grid-template-columns:1fr}
.se-sp--process__media{min-width:0;order:2}
.se-sp--process__grid .se-sp-steps{margin:0}
/*
 * A tall or wide slot no longer forces a ratio. The cell takes the ratio of the
 * source it holds, so a portrait stays portrait and a landscape stays landscape
 * and neither is cropped to a shape chosen for the layout rather than the
 * picture.
 */

/* --------------------------------------------------------------------------
   Checklist section

   Checks run full width and the aside sits beside a photograph underneath.
   Measured at 51% dead space below the shorter column before this layout.
   -------------------------------------------------------------------------- */
.se-sp--checklist__head{max-width:78ch}
.se-checks--wide{
  margin-top:24px;
  grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:14px 28px;
}
.se-sp--checklist__row{
  display:grid;gap:28px 40px;margin-top:30px;
  grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr);
  align-items:center;
}
.se-sp--checklist__row--single{grid-template-columns:1fr}
.se-sp--checklist__row--single .se-sp-aside{max-width:52ch}
.se-sp--checklist__media{min-width:0}


@media (max-width:900px){
  .se-sp--process__grid,
  .se-sp--checklist__row{grid-template-columns:1fr;gap:22px}
  .se-sp--process__media{order:0}

}

/* --------------------------------------------------------------------------
   Main introduction

   The section the brief singles out as the highest-priority layout: copy on one
   side, a service photograph on the other, roughly half and half, with the
   paragraph still held to a comfortable measure.

   It was a narrow measured column with nothing beside it, so the section read as
   a gap with a paragraph in it.
   -------------------------------------------------------------------------- */
.se-sp__grid--intro-photo{
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:32px 48px;
  /*
   * Centre, not stretch.
   *
   * This was stretch, on the stated reasoning that stretching "closes the band
   * at the same time, because the photograph is already set to fill its column".
   * It does close the band and it does not fill anything: stretching a grid item
   * makes its box as tall as the row while its text stays where it was, so the
   * space simply moves inside the column instead of disappearing.
   *
   * Measured across the twenty-eight pages that use this variant, the copy column
   * was 528px tall with its last line ending at 231px — 297px of empty box below
   * the paragraph on the shortest pages and 239px on the longest. The media column
   * beside it is not the photograph alone but two stacked portrait photographs,
   * 526px together, and neither photograph had room to grow without being cropped.
   *
   * Centring is what this stylesheet already does for the flow and audit
   * variants, and the reason recorded there applies here exactly: the column is
   * put against the middle of the taller one, so the space reads as a deliberate
   * margin rather than as a gap the layout failed to fill. It halves the effect
   * and it costs nothing — no copy is invented, no picture is cropped, and the
   * section keeps its height.
   */
  align-items:center;
}
.se-sp__grid--intro-plain{
  grid-template-columns:minmax(0,74ch);
  justify-content:center;
}
.se-sp__grid--intro-photo .se-sp__lead{min-width:0}
.se-sp__grid--intro-photo .se-sp__media{
  min-width:0;
  /* Nudged up so the photograph's top edge lines up with the first line of
     copy rather than sitting below it, which reads as an alignment error. */
  margin-top:2px;
}
/*
 * The row of photographs takes its own height, and the copy column is measured
 * so a long introduction does not stretch the line length past readability.
 *
 * The previous rule forced the picture to match the copy column's height exactly.
 * That was a way of removing a gap, and it worked, but it meant cropping every
 * photograph to whatever height the prose happened to be. The row is now sized
 * by the sources it holds, which is both honest about the pictures and stable
 * across the breakpoints.
 */
/*
   Both columns centre.
 *
   Which one is shorter is not the same on every page, and that is the reason
   neither column is pinned. At 1440px the copy runs to 231px against a 526px
   stack of two photographs, so the copy is the short one; at 1280px the copy runs
   to 670px against a 440px stack and the photographs are the short one. Pinning
   the photographs to the top fixed the first case and left 227px of empty column
 * beneath them on the second.
 *
 * Centring the pair fixes both, because centring a column that is already the
 * tallest in the row is a no-op — it only moves the one that is short.
 */
.se-sp__grid--intro-photo .se-sp__lead{align-self:center}
.se-sp__grid--intro-photo .se-sp__media{align-self:center}
.se-sp__grid--intro-photo .se-sp-intro__prose p{max-width:62ch}

@media (max-width:900px){
  .se-sp__grid--intro-photo{grid-template-columns:1fr;gap:22px}
  .se-sp__grid--intro-photo .se-sp__media{order:-1}
  .se-sp__grid--intro-photo .se-spphoto{aspect-ratio:16/10}
  /*
   * One photograph keeps its own shape. The 16/10 above is for a row of small
   * sources, which has to be given a height in order to sit two deep; a single
   * picture at full column width is already the right height, and forcing the
   * ratio crops the top and bottom off it for nothing.
   */
  .se-sp__grid--intro-photo .se-spphoto--1{aspect-ratio:auto}
}

/* --------------------------------------------------------------------------
   Hero: the photograph fills its column

   The hero image was sized from its own aspect ratio, so a short banner in a
   tall column left a band of empty space under it. Every hero measured between
   26% and 33% dead space below its content for that reason.

   The column now stretches to match the copy and the photograph covers it. A
   banner source is cropped rather than letterboxed, and object-position keeps
   the subject, which for these photographs is in the upper two thirds.

   Scoped to the split variant: the centred variant puts the media under the
   copy full width and is not affected.
   -------------------------------------------------------------------------- */
/*
 * The reversed hero.

 * The approved packages give several service pages a reversed hero composition,
 * and the renderer emitted a .se-sphero--reverse class for them, but no rule
 * anywhere matched that class. The variant therefore rendered pixel for pixel as
 * the ordinary split hero, so pages that were supposed to differ in composition
 * looked identical. Implemented here rather than removed, because the difference
 * is what the package asked for.

 * Also carries the stretch treatment below, so both two-column variants balance.
 */
.se-sphero--reverse .se-sphero__inner{grid-template-columns:minmax(0,1fr) minmax(0,1.04fr)}
.se-sphero--reverse .se-sphero__media{order:-1}

.se-sphero--split .se-sphero__inner{align-items:stretch}
.se-sphero--reverse .se-sphero__inner{align-items:stretch}
.se-sphero--split .se-sphero__content,
.se-sphero--reverse .se-sphero__content{align-self:center}
/*
   The media column keeps its own height rather than being stretched to match the
   copy. Stretching meant every hero photograph was cropped to whatever height
   the prose happened to be, and on a short hero it left a dead band under the
   picture. The columns now end where their own content ends.
*/
.se-sphero--split .se-sphero__media,
.se-sphero--reverse .se-sphero__media{min-width:0;align-self:center}

@media (max-width:820px){
  /* Three photographs side by side is too narrow to read at this width, and a
     three-across grid inside a full-width column would scale each cell down to
     roughly a third of the source, so it drops to two. */
  .se-sphero__band--3{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* Below the two-column breakpoint the copy comes first again, whichever way
     round the columns were. */
  .se-sphero--reverse .se-sphero__media{order:0}
}

@media (max-width:560px){
  /* One per line. A single photograph per line is the only composition that
     cannot run past the column, and the cell is still bounded by the source
     ratio and by its own width, so nothing is stretched. */
  .se-sphero__band--2,
  .se-sphero__band--3{grid-template-columns:minmax(0,1fr)}
}

/* --------------------------------------------------------------------------
   Split section: the picture matches the copy column

   The split grid centres its columns so a row of photographs taller than the
   copy does not leave the copy floating, and the media column is aligned to the
   top so a short row does not sit marooned in the middle of a tall column.

   The columns are not stretched to a common height. Forcing both to the taller
   of the two is what produced the dead band under a short picture, and forcing
   the picture to the copy's height cropped every photograph to the length of
   the prose beside it. Each column now ends where its own content ends, which
   is the layout the brief asks for: the space beside the copy is filled with
   service photography rather than padding.
   -------------------------------------------------------------------------- */
.se-sp__grid--split{align-items:start}
.se-sp__grid--split > .se-sp__lead{align-self:center}
.se-sp__grid--split > .se-sp__media{min-width:0}

/*
 * A split with no photograph. The media column is not emitted at all, so the
 * grid would otherwise reserve half its width for nothing. Collapsing to one
 * column gives the copy the full measure, which is the editorial layout the
 * brief asks for in place of invented artwork.
 */
.se-sp__grid--single{grid-template-columns:minmax(0,1fr)}
.se-sp__grid--single > .se-sp__lead{max-width:74ch}

@media (max-width:900px){
  .se-sp__grid--split > .se-sp__lead{align-self:auto}
}

/* --------------------------------------------------------------------------
   Intro block: heading across the top, keylist in two columns beneath

   This grid put a short heading block in one column and a five-item keylist in
   the other, aligned to the top. On the pages where the heading is only an
   eyebrow and two lines that measured a 63% shortfall under the left column, a
   visible hole beside the list.

   The heading now spans the container and the list runs underneath in two
   columns. It reads as an editorial section, it uses the width the two-column
   grid was not using, and it holds whether or not the block carries body copy.
   -------------------------------------------------------------------------- */
@media (min-width:901px){
  .se-sp__grid--intro{
    grid-template-columns:minmax(0,1fr);
    gap:26px 44px;
  }
  .se-sp__grid--intro > .se-sp__lead{max-width:76ch}
  .se-sp__grid--intro > .se-sp-keylist{
    grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:44px;row-gap:18px;
    align-items:start;
  }
  /* An odd final item spans both columns rather than leaving a gap beside it. */
  .se-sp__grid--intro > .se-sp-keylist > li:last-child:nth-child(odd){grid-column:1 / -1}
}

/* --------------------------------------------------------------------------
   Flow and audit sections

   Both pair a generated diagram with a numbered list. Aligning the columns to
   the top left an empty band under the shorter one on every page, because the
   list is several times taller than the diagram. Centring puts the diagram
   against the middle of the list, which reads as a deliberate margin rather
   than as a gap the layout failed to fill.
   -------------------------------------------------------------------------- */
.se-sp__grid--flow,
.se-sp__grid--audit{align-items:center}

/*
   The audit column starts at the top instead.

   Its media column holds a photograph or the service card — 225px to 440px —
   against a column of scorecard groups that runs to 800px or more. Centring a
   225px panel in an 800px row left about 287px above and below it, and since the
   section heading sits above the grid in the two-column head band, the card read
   as floating in the middle of an empty column rather than as the start of one.
   Aligning it to the top puts it level with the first group card, which is where
   a reader's eye goes first.
*/
.se-sp__grid--audit{align-items:start}

/* --------------------------------------------------------------------------
   The service card travels with the reader

   Putting real content in the media column fixed the empty space beside the copy
   and created a different one: a 225px card against 1,400px of scorecard groups,
   which measured as 224px to 909px of shortfall depending on the page.

   Sticky is the right answer, and it is the one this stylesheet already uses for
   the /services/ panel. The card then stays in view for as long as its column
   lasts, so there is no empty rectangle at any scroll position: the reader sees
   the platforms, the sentence and the button even when they are halfway down a
   long section.

   align-self:start is required, or the item is stretched to the full row height
   and has no travel left in it.

   Not applied below 1024px: the columns stack there, the card is a block in
   normal flow, and a sticky block on a phone is a panel that follows the reader
   all the way down the page.
   -------------------------------------------------------------------------- */
@media (min-width:1024px){
  .se-sp__grid--split > .se-sp__media,
  .se-sp__grid--flow > .se-sp__media,
  .se-sp--process__media,
  .se-sp--checklist__media{
    position:sticky;
    top:calc(var(--se-header-h) + 20px);
    align-self:start;
  }
}

/* --------------------------------------------------------------------------
   Process steps beside the secondary photograph

   The steps keep three columns here, inherited from the full-width variant. In a
   745px column that left about 165px of text width per step, so each
   description wrapped to twelve or more lines and the steps read as three tall
   narrow ribbons rather than as a sequence. Two columns gives a usable measure.
   -------------------------------------------------------------------------- */
@media (min-width:901px){
  .se-sp--process__grid .se-sp-steps{
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:16px;
  }
}

/*
   Flow section

   With a photograph the list sits beside it and both columns centre against each
   other. Without one the list runs the full container in two columns, rather
   than leaving a column of nothing where a diagram used to be.
*/
.se-sp__grid--flow{align-items:center}
.se-sp__grid--flow .se-sp-media{order:2}

@media (min-width:901px){
  .se-sp__grid--flow-full{grid-template-columns:minmax(0,1fr)}
  .se-sp__grid--flow-full .se-sp-flow{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:44px;row-gap:20px;
  }
}

/* --------------------------------------------------------------------------
   The photograph row across the breakpoints

   A row of three is the desktop composition: three 192px portraits come to
   576px, which is very nearly the width of a media column in the 1280px
   container, so the pictures sit at the size they were delivered at.

   Going down, a row of three becomes a row of two and then a single column. It
   is not a carousel and it does not scroll sideways, so nothing can overflow
   horizontally at any width, and no photograph is ever enlarged to fill a
   narrower slot: the images shrink, because width is 100% and height follows
   the source's own ratio.
   -------------------------------------------------------------------------- */
@media (max-width:1100px){
  /*
   * Nothing to override.
   *
   * The row's columns are the photographs' own widths, so a narrower column is
   * handled by the cells wrapping: three 192px portraits no longer fit beside a
   * copy column at this width and the third moves to the next line on its own,
   * with no breakpoint-specific rule involved.
   */
}

@media (max-width:640px){
  /*
   * One cell per line, at the smaller of the column and the source.
   *
   * A single photograph per line is the only composition that cannot run past the
   * column. The cell is capped at min(100%, source width) rather than forced to
   * 100%: forcing it to 100% fixed the overflow but enlarged every 192px portrait
   * to 354px, which is a 1.84x upscale, and 604px at the 640px breakpoint, which
   * is 3.15x. The row is centred instead, so a photograph narrower than the
   * column sits deliberately rather than being stretched to fill it. A single
   * photograph already has those two rules and needs nothing added here.
   */
  .se-spphoto--2,
  .se-spphoto--3{grid-template-columns:minmax(0,1fr);gap:12px;justify-items:center}
  .se-spphoto--2 .se-spphoto__cell,
  .se-spphoto--3 .se-spphoto__cell{
    width:100%;
    max-width:min(100%, var(--se-cell-w,100%));
  }
  .se-sp__grid--single > .se-sp__lead{max-width:none}
}

@media (max-width:400px){
  .se-spphoto{gap:10px}
}
