/* ══════════ DESIGN TOKENS ══════════ */
:root{
  /* Brand, from the approved kit: navy #001251, electric blue #0249FC on light,
     blue #0965FF and white on dark, dark ground #172026. Do not resample these
     from an image: the kit is the source. */
  --bg:#F2F4F8; --bg-2:#FFFFFF; --bg-3:#E6EAF2; --bg-inv:#000000;
  --fg:#000000; --fg-2:#3A4048; --fg-3:#5A626D; --fg-inv:#F2F4F8;
  --line:#D7DBE4; --line-2:#B2B8C4; --edge:#767E8B;
  --accent:#0249FC; --accent-h:#0139C9; --accent-fg:#FFFFFF; --accent-soft:rgba(2,73,252,.07);
  --brass:#8A6620; --good:#116B45;
  --p:#0249FC; --p-fg:#FFFFFF;
  --chamfer:14px; --maxw:1240px;
  --f-d:'Archivo',system-ui,sans-serif;
  --f-b:'IBM Plex Sans',system-ui,sans-serif;
  --f-m:'IBM Plex Mono',ui-monospace,monospace;
  --shadow:0 1px 2px rgba(10,18,35,.05), 0 18px 40px -26px rgba(10,18,35,.4);

  /* The wash that lets words sit on a photograph. There were three of these,
     at three angles with three sets of stops: one on the home carousel, one on
     the article and case banners, one on the listing pages. Near enough to look
     like a mistake rather than a decision, and the home page was the only one
     that had been tuned. One definition now, used by all of them.

     var(--bg) resolves where the property is used, not here, so the light and
     dark grounds each get their own wash without a second declaration. */
  --scrim:linear-gradient(90deg,
    var(--bg) 0%,
    color-mix(in srgb,var(--bg) 94%,transparent) 38%,
    color-mix(in srgb,var(--bg) 38%,transparent) 62%,
    transparent 80%);
  --scrim-rtl:linear-gradient(270deg,
    var(--bg) 0%,
    color-mix(in srgb,var(--bg) 94%,transparent) 38%,
    color-mix(in srgb,var(--bg) 38%,transparent) 62%,
    transparent 80%);
  /* Narrow: the copy runs the full width, so a side wash would leave the last
     words on the picture. Near solid, lifting only at the foot. */
  --scrim-narrow:linear-gradient(180deg,
    color-mix(in srgb,var(--bg) 93%,transparent) 0%,
    color-mix(in srgb,var(--bg) 89%,transparent) 62%,
    color-mix(in srgb,var(--bg) 55%,transparent) 100%);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#172026; --bg-2:#1E2A32; --bg-3:#26343E; --bg-inv:#EAF0FE;
    --fg:#EAF0FE; --fg-2:#AEBCDD; --fg-3:#8D9BBD; --fg-inv:#000000;
    --line:#2A3740; --line-2:#3B4A55; --edge:#6D7AAB;
    --accent:#5F9BFF; --accent-h:#8AB6FF; --accent-fg:#172026; --accent-soft:rgba(95,155,255,.15);
    --brass:#D6A75E; --good:#4FC08D;
    --p:#5F9BFF; --p-fg:#172026;
    --shadow:0 1px 2px rgba(0,0,0,.5), 0 22px 48px -28px rgba(0,0,0,.9);
  }
}
:root[data-theme="dark"]{
  --bg:#172026; --bg-2:#1E2A32; --bg-3:#26343E; --bg-inv:#EAF0FE;
  --fg:#EAF0FE; --fg-2:#AEBCDD; --fg-3:#8D9BBD; --fg-inv:#000000;
  --line:#2A3740; --line-2:#3B4A55; --edge:#6D7AAB;
  --accent:#5F9BFF; --accent-h:#8AB6FF; --accent-fg:#172026; --accent-soft:rgba(95,155,255,.15);
  --brass:#D6A75E; --good:#4FC08D;
  --p:#5F9BFF; --p-fg:#172026;
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 22px 48px -28px rgba(0,0,0,.9);
}

/* per-product accents, legible on both grounds */
.p-desq{--p:#0C7A72; --p-fg:#FFFFFF}
.p-rovix{--p:#A9511A; --p-fg:#FFFFFF}
.p-servexa{--p:#54459F; --p-fg:#FFFFFF}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .p-desq{--p:#3DCCC0; --p-fg:#04231F}
  :root:not([data-theme="light"]) .p-rovix{--p:#F0964F; --p-fg:#2A1204}
  :root:not([data-theme="light"]) .p-servexa{--p:#9E8DF5; --p-fg:#100A2E}
}
:root[data-theme="dark"] .p-desq{--p:#3DCCC0; --p-fg:#04231F}
:root[data-theme="dark"] .p-rovix{--p:#F0964F; --p-fg:#2A1204}
:root[data-theme="dark"] .p-servexa{--p:#9E8DF5; --p-fg:#100A2E}

*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--f-b);font-size:16px;line-height:1.62;-webkit-font-smoothing:antialiased}
html[dir="rtl"] body,html[dir="rtl"] button,html[dir="rtl"] input,html[dir="rtl"] select,html[dir="rtl"] textarea{font-family:'IBM Plex Sans Arabic','IBM Plex Sans',system-ui,sans-serif}
html[dir="rtl"] h1,html[dir="rtl"] h2,html[dir="rtl"] h3,html[dir="rtl"] h4,html[dir="rtl"] h5{font-family:'IBM Plex Sans Arabic','IBM Plex Sans',system-ui,sans-serif;font-weight:600}
/* Archivo and IBM Plex Mono carry no Arabic, so every label set in them fell
   through to whatever face the device happened to have, at the wrong weight
   and width. Redefining the variable fixes every rule that uses it at once.
   Uppercase does nothing in Arabic, and tracking breaks the cursive joins. */
html[dir="rtl"]{--f-m:'IBM Plex Sans Arabic','IBM Plex Sans',system-ui,sans-serif;--f-d:'IBM Plex Sans Arabic','IBM Plex Sans',system-ui,sans-serif}
html[dir="rtl"] .mono,html[dir="rtl"] .hero-stats .l,html[dir="rtl"] .lnk,html[dir="rtl"] .eyeb,html[dir="rtl"] .slide-copy .eyeb,html[dir="rtl"] .tagline,html[dir="rtl"] .hero-badge{text-transform:none;letter-spacing:0}
html[dir="rtl"] code,html[dir="rtl"] pre{font-family:'IBM Plex Mono',ui-monospace,monospace}
h1,h2,h3,h4,h5{font-family:var(--f-d);font-weight:700;line-height:1.13;margin:0;letter-spacing:-.021em;text-wrap:balance}
html[dir="rtl"] h1,html[dir="rtl"] h2,html[dir="rtl"] h3,html[dir="rtl"] h4,html[dir="rtl"] h5{letter-spacing:0;line-height:1.35}
p{margin:0}
ul{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
img,svg{max-width:100%}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.mono{font-family:var(--f-m);font-size:.7rem;letter-spacing:.11em;text-transform:uppercase}
html[dir="rtl"] .mono{letter-spacing:.02em}
.chamfer{clip-path:polygon(0 0,calc(100% - var(--chamfer)) 0,100% var(--chamfer),100% 100%,var(--chamfer) 100%,0 calc(100% - var(--chamfer)))}
html[dir="rtl"] .chamfer{clip-path:polygon(var(--chamfer) 0,100% 0,100% calc(100% - var(--chamfer)),calc(100% - var(--chamfer)) 100%,0 100%,0 var(--chamfer))}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 28px}
[hidden]{display:none!important}

/* ══════════ HEADER ══════════ */
.utility{background:var(--bg-3);border-bottom:1px solid var(--line);font-size:.78rem}
.utility .wrap{display:flex;align-items:center;gap:16px;min-height:38px;color:var(--fg-3)}
.utility .spacer{margin-inline-start:auto}
.seg{display:flex;border:1px solid var(--edge);background:var(--bg-2)}
.seg button{font-family:var(--f-m);font-size:11px;letter-spacing:.08em;text-transform:uppercase;padding:5px 10px;background:none;border:0;color:var(--fg-3);cursor:pointer}
.seg button[aria-pressed="true"]{background:var(--accent);color:var(--accent-fg)}
html[dir="rtl"] .seg button{letter-spacing:.02em}

header.site{position:sticky;top:0;z-index:60;background:color-mix(in srgb,var(--bg) 90%,transparent);backdrop-filter:blur(16px);border-bottom:1px solid var(--line)}
header.site .wrap{display:flex;align-items:center;gap:12px;min-height:70px}
.logo{display:flex;align-items:center;margin-inline-end:26px;flex:none}
.logo img{display:block;width:auto;height:46px}
@media(max-width:520px){.logo img{height:38px}}
.logo .on-dark{display:none}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .logo .on-light{display:none}
  :root:not([data-theme="light"]) .logo .on-dark{display:block}
}
:root[data-theme="dark"] .logo .on-light{display:none}
:root[data-theme="dark"] .logo .on-dark{display:block}
.tagline{font-family:var(--f-m);font-size:.6rem;letter-spacing:.19em;text-transform:uppercase;color:var(--fg-3);margin-top:14px}
html[dir="rtl"] .tagline{letter-spacing:.04em}
nav.main{display:flex;gap:2px;align-items:center}
nav.main>div{position:relative}
nav.main a,nav.main button.navtop{
  font:500 .89rem/1 var(--f-b);color:var(--fg-2);padding:10px 13px;background:none;border:0;cursor:pointer;
  display:inline-flex;align-items:center;gap:5px;font-family:inherit;
}
nav.main a:hover,nav.main button.navtop:hover{color:var(--fg)}
nav.main a.on{color:var(--accent)}
.drop{position:absolute;inset-inline-start:0;top:calc(100% + 10px);width:330px;background:var(--bg-2);border:1px solid var(--line);box-shadow:var(--shadow);padding:8px;z-index:70}
.drop a{display:flex;gap:12px;padding:11px 12px;align-items:flex-start;width:100%}
.drop a:hover{background:var(--bg-3)}
.drop .dm{width:30px;height:30px;flex:none}
.drop b{font-family:var(--f-d);font-size:.9rem;display:block;color:var(--fg)}
.drop span{font-size:.78rem;color:var(--fg-3);display:block;line-height:1.45}
.drop .foot{border-top:1px solid var(--line);margin-top:6px;padding:10px 12px}
.hdr-actions{margin-inline-start:auto;display:flex;align-items:center;gap:10px;flex:none}
.burger{display:none;background:none;border:1px solid var(--line-2);color:var(--fg);padding:8px 11px;cursor:pointer;font-family:var(--f-m);font-size:.68rem}
/* Phones. The header actions were set never to shrink, so on a narrow screen
   the search field and the call to action pushed the whole page wider than the
   viewport: every line of text was cut off at the right, and the menu button
   sat off-screen entirely, which left no way to navigate at all. */
@media(max-width:720px){
  /* Four figures in a row cannot fit on a phone. A flex item will not shrink
     below its content by default, so these were holding the whole document
     wider than the screen and clipping every line of text on the page. */
  .hero-stats,.p-metrics{flex-wrap:wrap}
  .hero-stats>div,.p-metrics>div{flex:1 1 50%;min-width:0;padding:16px 18px}
  .hero-stats>div:nth-child(2n),.p-metrics>div:nth-child(2n){border-inline-end:0}
  .hero-stats>div,.p-metrics>div{border-top:1px solid var(--line)}
}
@media(max-width:420px){
  .hero-stats>div,.p-metrics>div{flex:1 1 100%;border-inline-end:0}
}
@media(max-width:720px){
  .hdr-actions{flex:1 1 auto;min-width:0}
  .hdr-search{flex:1 1 auto;min-width:0}
  .hdr-search input{width:100%;min-width:0}
}
@media(max-width:560px){
  .wrap{padding:0 18px}
  .utility .wrap{flex-wrap:wrap;gap:10px;padding-top:7px;padding-bottom:7px}
  /* The strapline is in the footer as well, and on a phone the switchers are
     what the bar is for. */
  .utility .wrap>span:first-child{display:none}
  .utility .spacer{display:none}
  .hdr-search{display:none}
  .site .wrap{gap:10px}
}
@media(max-width:1080px){
  nav.main{display:none;position:absolute;top:100%;inset-inline:0;background:var(--bg-2);border-bottom:1px solid var(--line);flex-direction:column;align-items:stretch;padding:10px 18px 18px}
  nav.main.open{display:flex}
  nav.main a,nav.main button.navtop{padding:12px 4px;font-size:1rem;justify-content:flex-start}
  .drop{position:static;width:auto;border:0;box-shadow:none;padding:0 0 8px 14px;background:none}
  .burger{display:inline-flex}
}
@media(max-width:640px){.hdr-actions .btn{display:none}}

.hdr-search{display:flex;align-items:center;gap:8px;border:1px solid var(--edge);background:var(--bg-2);padding:0 11px;height:38px}
.hdr-search svg{width:15px;height:15px;color:var(--fg-3);flex:none}
.hdr-search input{border:0;background:none;color:var(--fg);font:400 .85rem/1 var(--f-b);font-family:inherit;width:120px;outline:none;padding:0}
.hdr-search input::placeholder{color:var(--fg-3)}
.hdr-search:focus-within{border-color:var(--accent)}
@media(max-width:1180px){.hdr-search{display:none}}
.searchbig{display:flex;gap:10px;max-width:620px}
.searchbig input{flex:1;border:1px solid var(--edge);background:var(--bg-2);color:var(--fg);padding:13px 15px;font:400 .95rem/1 var(--f-b);font-family:inherit}
.searchbig input:focus{border-color:var(--accent);outline:none}

/* ══════════ BUTTONS ══════════ */
.btn{display:inline-flex;align-items:center;gap:8px;font:600 .88rem/1 var(--f-b);font-family:inherit;padding:13px 20px;border:1px solid transparent;cursor:pointer;white-space:nowrap}
.btn-p{background:var(--accent);color:var(--accent-fg)}
.btn-p:hover{background:var(--accent-h)}
.btn-o{border-color:var(--edge);color:var(--fg);background:none}
.btn-o:hover{border-color:var(--fg-3)}
.btn-pr{background:var(--p);color:var(--p-fg)}
.btn-sm{padding:10px 15px;font-size:.82rem}
.lnk{color:var(--accent);font-family:var(--f-m);font-size:.72rem;letter-spacing:.09em;text-transform:uppercase;display:inline-flex;gap:7px;align-items:center}
html[dir="rtl"] .lnk{letter-spacing:.02em}
html[dir="rtl"] .lnk .ar{transform:scaleX(-1)}

/* ══════════ SECTIONS ══════════ */
.sec{padding:68px 0;border-bottom:1px solid var(--line);position:relative}

/* Alternate the ground so a run of sections reads as a sequence rather than as
   one long page. The band is set on the section, not on a wrapper, so the
   colour runs the full width of the viewport. */
.sec:nth-of-type(even){background:var(--bg-2)}
.sec--tight{padding:48px 0}
.sec--flush{border-bottom:0}
.sec-tight{padding:56px 0}
.eyebrow{color:var(--accent);display:flex;align-items:center;gap:12px;margin-bottom:16px}
.eyebrow::after{content:"";height:1px;background:var(--line);flex:1;max-width:180px}
/* Heading on the left, its supporting line opposite, so the top of a section
   is not a short phrase followed by six hundred pixels of nothing. */
.sec-h{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:20px 56px;align-items:end;margin-bottom:34px;
}
.sec-h > *{min-width:0}
/* A heading with nothing opposite should not hold a column open for it. */
.sec-h:not(:has(> * + *)){grid-template-columns:minmax(0,1fr)}
.sec-h h2{font-size:clamp(1.6rem,3vw,2.2rem);line-height:1.12;letter-spacing:-.026em}
.sec-h .lede,.sec-h p{color:var(--fg-2);max-width:48ch;padding-bottom:0}
.sec-aside{display:flex;flex-direction:column;gap:12px;align-items:flex-start;padding-bottom:4px}
@media (max-width:860px){.sec-h{grid-template-columns:1fr;gap:14px}}
.sec-h h2{font-size:clamp(1.6rem,3.4vw,2.35rem);flex:1;min-width:260px;max-width:22ch}
.sec-h .aside{max-width:42ch;color:var(--fg-2);font-size:.95rem}
.lede{color:var(--fg-2);font-size:1.08rem;max-width:66ch}
/* A fixed grid takes its column count from --cols where the template sets one,
   so six things never render as four and two holes. The narrow breakpoints
   override it, because the property is inline and would otherwise win. */
.grid{display:grid;gap:20px}
.g2{grid-template-columns:repeat(var(--cols,2),minmax(0,1fr))}
.g3{grid-template-columns:repeat(var(--cols,3),minmax(0,1fr))}
.g4{grid-template-columns:repeat(var(--cols,4),minmax(0,1fr))}
@media(max-width:980px){.g3,.g4{grid-template-columns:repeat(2,minmax(0,1fr))!important}}
@media(max-width:680px){.g2,.g3,.g4{grid-template-columns:1fr!important}}

/* ══════════ HERO ══════════ */
.hero{position:relative;overflow:hidden;padding:118px 0 104px;border-bottom:1px solid var(--line)}
/* ══════════ PRACTICE GROUPS ══════════
   The services index is grouped by the five practices rather than listing
   twenty identical cards, so the reader can see the shape of what is on offer
   before reading any of it. */
.practice{padding-top:44px;margin-top:44px;border-top:1px solid var(--line)}
.practice--first{padding-top:0;margin-top:0;border-top:0}
.practice-h{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:16px 56px;align-items:end;margin-bottom:24px;
}
.practice-h h2{font-size:clamp(1.3rem,2.2vw,1.65rem);letter-spacing:-.022em;line-height:1.16}
.practice-h .eyebrow{color:var(--accent)}
.practice-h .aside{color:var(--fg-2);max-width:46ch;font-size:.93rem}
@media (max-width:860px){.practice-h{grid-template-columns:1fr;gap:10px}}

/* The enquiry form keeps its own width and the rail sits beside it, so the
   contact page is not one box floating in the middle of an empty screen. */
.enquiry-cols{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,300px);
  gap:26px 56px;align-items:start;
}
.rail-bullets{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.rail-bullets li{
  color:var(--fg-2);font-size:.9rem;line-height:1.5;
  padding-inline-start:15px;position:relative;
}
.rail-bullets li::before{
  content:"";position:absolute;inset-inline-start:0;top:.62em;
  width:5px;height:5px;background:var(--accent);border-radius:50%;
}
.rail-note{color:var(--fg-2);font-size:.88rem;line-height:1.55}
.rail-note a{color:var(--accent)}
.rail-lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.rail-lines li{color:var(--fg-2);font-size:.9rem;line-height:1.5}
.rail-lines a{color:var(--fg)}
.rail-lines a:hover{color:var(--accent)}
@media (max-width:1000px){
  .enquiry-cols{grid-template-columns:minmax(0,1fr)}
}

/* ══════════ READING COLUMN AND RAIL ══════════
   A solution page was sixty words in a seventy character column with five
   hundred pixels of nothing beside it. The links that belong there already
   existed in the content and rendered nowhere.

   The column keeps its measure either way. The rail appears only when there is
   something to put in it, and the modifier below closes the grid up when there
   is not, so an empty half is never held open. */
/* The column is set to its reading measure and the rail to its own width, and
   the slack goes between them. Letting the first column take the remaining
   width instead left the text ending well short of the rail, with a band of
   nothing down the middle of the page. */
.entry-cols{
  display:grid;grid-template-columns:minmax(0,68ch) minmax(240px,300px);
  justify-content:space-between;gap:26px 56px;align-items:start;
}
.entry-cols--alone{grid-template-columns:minmax(0,72ch)}
/* Unless what is inside it is a split body, which wants the whole measure:
   headings down one side, prose down the other. Capped at seventy two
   characters it would be two narrow columns inside one narrow column. */
.entry-cols--alone:has(.entry--split){grid-template-columns:minmax(0,1fr)}

.rail{display:flex;flex-direction:column;gap:16px;position:sticky;top:96px}
.rail-card{border:1px solid var(--line);background:var(--bg-2);padding:18px 20px}
.rail-card .eyebrow{color:var(--fg-3);margin-bottom:12px}
.rail-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.rail-list li + li{border-top:1px solid var(--line);margin-top:9px;padding-top:9px}
.rail-list a{color:var(--fg);font-size:.92rem;line-height:1.4;display:block}
.rail-list a:hover{color:var(--accent)}
.rail-ask{background:var(--bg-3);border-color:var(--line-2)}
.rail-ask p{color:var(--fg-2);font-size:.9rem;margin-bottom:14px}
.rail-ask .btn{width:100%;justify-content:center}

@media (max-width:1000px){
  .entry-cols{grid-template-columns:minmax(0,1fr)}
  .rail{position:static;flex-direction:row;flex-wrap:wrap}
  .rail-card{flex:1 1 260px}
}

/* ══════════ PRODUCT SCREENS ══════════
   The interfaces are the most persuasive thing on a product page, so they get
   the width of the section rather than a third of it.

   They are also different shapes on purpose: a dashboard is wide, a floor plan
   is wide, a pair of phones is not. Dropped into one equal grid they tiled
   ragged and left a lone image alone on a second row. The first runs the full
   width and the rest sit under it, which reads as a lead view and its
   supporting ones however many there happen to be. */
.shots{display:grid;gap:20px}
/* Each supporting view keeps its own height. Forcing them to a common one
   pushed the caption of the widest, shortest picture a hundred pixels clear of
   its image and left a white gap that read as a loading failure. */
.shots-rest{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px;align-items:start}
.shot-figure{
  margin:0;border:1px solid var(--line);background:var(--bg-2);
  display:flex;flex-direction:column;overflow:hidden;
}
.shot-figure img{display:block;width:100%;height:auto}
.shot-figure figcaption{
  margin-top:auto;padding:13px 17px;border-top:1px solid var(--line);
  background:var(--bg-2);font-size:.84rem;color:var(--fg-2);
}
/* The lead is a wide interface, so it sits on the section ground rather than
   in a box of its own, and the caption is the only framing it needs. */
.shot-figure--lead{border-color:var(--line-2);box-shadow:0 22px 50px -34px rgba(10,18,35,.55)}
@media (max-width:700px){
  .shots-rest{grid-template-columns:1fr}
}

/* ══════════ DOWNLOAD STRIP ══════════
   A document offer across the width, with the file details on one side and the
   action on the other. It replaced a narrow card sitting alone in a full width
   band, which left most of the section empty. */
.download-strip{
  background:var(--bg-2);border:1px solid var(--line);padding:26px 28px;
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:28px;align-items:center;
  border-inline-start:3px solid var(--p);
}
.download-strip h3{font-size:1.24rem;letter-spacing:-.016em;margin:2px 0 6px}
.download-strip p{color:var(--fg-2);font-size:.92rem;max-width:62ch}
.download-act{display:flex;align-items:center;gap:16px;flex:none}
.download-meta{
  font-family:var(--f-m);font-size:.7rem;letter-spacing:.08em;color:var(--fg-3);
  border:1px solid var(--line);padding:5px 9px;white-space:nowrap;
}
html[dir="rtl"] .download-meta{letter-spacing:.02em}
@media (max-width:760px){
  .download-strip{grid-template-columns:1fr;gap:18px}
  .download-act{flex-wrap:wrap}
}

/* ══════════ PAGE HEADER ══════════
   A split: words on one side, the section's photograph running to the edge of
   the viewport on the other. It replaced a full width background behind the
   words, which needed so much scrim to stay readable that the photograph
   disappeared, and which left the right half of every listing page empty. */
/* The banner on an inner page is the same idea as a carousel slide and used to
   be built differently: the picture boxed into the right 44% with a hard edge
   down the middle, and the words on flat colour beside it. Two treatments for
   one job, and the weaker one on every page that is not the home page.

   It is the slide now. Full bleed picture, the same horizontal scrim, and the
   words sitting on the solid side of it. The gradient stops are shared with
   .slide-bg::after deliberately: if one is ever retuned, the other has to move
   with it or the site goes back to having two heroes. */
.pagehead{isolation:isolate;overflow:hidden}
.pagehead-media{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--bg-3)}
.pagehead-media img{width:100%;height:100%;object-fit:cover;display:block}
.pagehead-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;background:var(--scrim)}
html[dir="rtl"] .pagehead-scrim{background:var(--scrim-rtl)}
.pagehead > .wrap{position:relative;z-index:2}
.pagehead h1{max-width:16ch}
.pagehead .lede{max-width:52ch}
/* A banner with a picture behind it needs the height to read as one. Without a
   picture it stays compact, because there is nothing to show. */
.pagehead:has(.pagehead-media){min-height:clamp(300px,38vh,420px);display:flex;align-items:center}
.pagehead:has(.pagehead-media) > .wrap{width:100%}
@media (max-width:820px){
  /* Narrow: the words run the full width, so a side gradient would leave the
     last of them on the picture. Near solid instead, exactly as the slide. */
  .pagehead-scrim,html[dir="rtl"] .pagehead-scrim{background:var(--scrim-narrow)}
  .pagehead:has(.pagehead-media){min-height:260px}
}

/* the plain panel that replaced the globe fallback */
.hero-media--plain,.hero-panel--plain{
  position:absolute;inset:0;
  background:linear-gradient(135deg, var(--bg-3) 0%, var(--bg-2) 58%, var(--bg-3) 100%);
}
.hero-panel--plain{position:relative;width:100%;height:100%;min-height:280px}
.hero-arcs{position:absolute;inset-inline-end:-160px;top:-120px;width:640px;height:640px;opacity:.42;pointer-events:none}
.hero h1{font-size:clamp(2.3rem,5.6vw,4.1rem);font-weight:800;max-width:16ch;margin:20px 0 0;line-height:1.04;letter-spacing:-.032em}
.hero .lede{margin-top:22px}
.hero-btns{display:flex;gap:12px;margin-top:32px;flex-wrap:wrap}
.hero-meta{display:flex;gap:28px;margin-top:44px;flex-wrap:wrap;color:var(--fg-3)}
.hero-meta div{display:flex;gap:9px;align-items:center}
.tick{width:15px;height:15px;flex:none;color:var(--accent)}

/* ══════════ HERO: configurable variants ══════════
   Every hero on the site is one component with a style setting. The markup
   below covers a motion background, a split with a media panel, a rotating
   carousel and the plain version. Which one runs is a field in the CMS, not a
   different template. */
.hero-v{position:relative;border-bottom:1px solid var(--line);overflow:hidden}
.hero-v .wrap{position:relative;z-index:2}

/* backdrop layers, shared by every variant that has one */
.hero-media{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--bg-3)}
.hero-media video,.hero-media img,.hero-media canvas{width:100%;height:100%;object-fit:cover;display:block}
.hero-scrim{position:absolute;inset:0;z-index:1;pointer-events:none}

/* The scrim keeps text legible over any media, and differs per theme because
   the underlying ground does. Shared with the carousel and the listing banners:
   one wash for every hero on the site. */
.hero-v--video .hero-scrim{background:var(--scrim)}
html[dir="rtl"] .hero-v--video .hero-scrim{background:var(--scrim-rtl)}
@media (max-width:820px){
  .hero-v--video .hero-scrim,
  html[dir="rtl"] .hero-v--video .hero-scrim{background:var(--scrim-narrow)}
}

.hero-v--video{padding:104px 0 92px}
.hero-v--minimal{padding:96px 0 84px}
.hero-inner{max-width:none}
.hero-v h1{font-size:clamp(2.1rem,5.1vw,3.65rem);font-weight:800;max-width:17ch;margin:18px 0 0}
.hero-v .lede{margin-top:22px}
.hero-v .hero-btns{display:flex;gap:12px;margin-top:32px;flex-wrap:wrap}

/* the small "this is a placeholder" chip on the motion background */
.hero-badge{
  position:absolute;z-index:3;inset-block-end:14px;inset-inline-end:18px;
  font-family:var(--f-m);font-size:.58rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--fg-3);background:color-mix(in srgb,var(--bg) 80%,transparent);
  border:1px solid var(--line);padding:5px 9px;
}
html[dir="rtl"] .hero-badge{letter-spacing:.02em}

/* ── image backed ── */
.hero-v--image .hero-media img{filter:saturate(1.05)}

/* ── centred: for a short, declarative line ── */
.hero-v--centred{padding:112px 0 100px;text-align:center}
.hero-v--centred h1{margin-inline:auto;max-width:20ch}
.hero-v--centred .lede{margin-inline:auto}
.hero-v--centred .hero-scrim{
  background:radial-gradient(120% 90% at 50% 50%, color-mix(in srgb,var(--bg) 55%,transparent) 0%, color-mix(in srgb,var(--bg) 92%,transparent) 72%);
}
.eyebrow--centre{justify-content:center}
.eyebrow--centre::after{display:none}
.hero-btns--centre{justify-content:center}

/* ── gradient: no media at all, brand colour carries it ── */
.hero-v--gradient{
  padding:104px 0 96px;
  background:linear-gradient(118deg,#001251 0%,#0A2280 46%,#0249FC 100%);
  color:#EAF0FE;
}
html[dir="rtl"] .hero-v--gradient{background:linear-gradient(242deg,#001251 0%,#0A2280 46%,#0249FC 100%)}
.hero-v--gradient h1{color:#FFFFFF}
.hero-v--gradient .lede{color:rgba(234,240,254,.82)}
.hero-v--gradient .eyebrow{color:#9FBEFF}
.hero-v--gradient .eyebrow::after{background:rgba(159,190,255,.35)}
.hero-btn-invert{background:#FFFFFF;color:#001251}
.hero-btn-invert:hover{background:#EAF0FE}
.hero-btn-ghost{border-color:rgba(234,240,254,.5);color:#EAF0FE}
.hero-btn-ghost:hover{border-color:#FFFFFF}

/* ── split: copy beside a media panel ── */
.hero-v--split{padding:0}
.hero-split{display:grid;grid-template-columns:1.05fr .95fr;align-items:stretch;gap:0}
@media(max-width:900px){.hero-split{grid-template-columns:1fr}}
.hero-split-copy{padding:88px 0 84px;padding-inline-end:56px}
@media(max-width:900px){.hero-split-copy{padding:64px 0 40px}}
.hero-split-media{position:relative;min-height:440px;background:var(--bg-3);border-inline-start:1px solid var(--line);overflow:hidden}
@media(max-width:900px){.hero-split-media{min-height:280px;border-inline-start:0;border-top:1px solid var(--line);margin-bottom:0}}
.hero-split-media video,.hero-split-media img,.hero-split-media canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.hero-play{
  position:absolute;z-index:2;inset-block-end:20px;inset-inline-start:20px;
  display:flex;align-items:center;gap:11px;background:var(--bg-2);border:1px solid var(--edge);
  padding:10px 16px;font:600 .82rem/1 var(--f-b);font-family:inherit;color:var(--fg);cursor:pointer;
}
.hero-play svg{width:13px;height:13px;color:var(--accent);flex:none}

/* ══════════ HERO: THE PRODUCT SCREENS ══════════
   The home page used to open on a rotating wireframe globe, which said nothing
   about the business and which the owner asked twice to be rid of. It opens on
   the products now: their own interfaces, stacked back to front so the first
   one is on top, each carrying its own name and accent inside the picture.

   The stack bleeds off the right edge on purpose. A screen cut by the edge of
   the page reads as a window onto something larger; the same screen fully
   contained reads as a thumbnail. */
.hero-v--showcase{
  padding:0;background:var(--bg);border-bottom:1px solid var(--line);
  overflow:hidden;position:relative;
}
.hero-v--showcase .hero-split{grid-template-columns:minmax(0,1fr) minmax(0,1.02fr);align-items:center}
.hero-v--showcase .hero-split-copy{padding:96px 0 92px;padding-inline-end:64px}

.hero-fan{position:relative;min-height:376px;align-self:center}
.hero-fan-item{
  position:absolute;margin:0;width:104%;
  top:calc(var(--i) * 58px);inset-inline-start:calc(var(--i) * 40px);
  z-index:var(--i);
  border:1px solid var(--line-2);border-radius:10px;overflow:hidden;
  background:var(--bg-2);
  box-shadow:0 26px 60px -28px rgba(10,18,35,.55);
}
.hero-fan-item img{display:block;width:100%;height:auto}
/* The topmost screen carries its product's colour along its head, which is the
   only thing here that is not already in the picture. */
.hero-fan-item::after{
  content:"";position:absolute;top:0;inset-inline-start:0;width:100%;height:3px;
  background:var(--p,var(--accent));
}

@media (max-width:1100px){
  .hero-fan{min-height:300px}
  .hero-fan-item{width:112%}
}
@media (max-width:900px){
  /* The one column rule on .hero-split is a single class and loses to this
     component's own two column rule, which has one more, so it has to be
     restated here or the stack keeps sitting beside the copy on a phone. */
  .hero-v--showcase .hero-split{grid-template-columns:minmax(0,1fr)}
  .hero-v--showcase .hero-split-copy{padding:64px 0 8px;padding-inline-end:0}
  .hero-fan{min-height:250px;margin-bottom:56px}
  /* Width has to make room for the offsets, or the last card in the stack sits
     past the edge of the screen and is clipped mid table. */
  .hero-fan-item{width:calc(100% - 44px);top:calc(var(--i) * 40px);inset-inline-start:calc(var(--i) * 22px)}
}
@media (prefers-reduced-motion:no-preference){
  .hero-fan-item{transition:transform .35s ease}
  .hero-fan:hover .hero-fan-item{transform:translateY(-4px)}
}

/* ── stat strip under a hero ── */
/* Four ways in, immediately under the hero. These were four lines of small
   grey text on a hairline; they are the first choice a visitor makes, so they
   are now sized like a choice. */
.hero-stats{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:1px solid var(--line);background:var(--bg-2);position:relative;z-index:2;
  /* The band runs edge to edge but its content lines up with the page grid,
     so the first route starts under the headline rather than 100px to its left. */
  padding-inline:max(28px, calc((100% - var(--maxw)) / 2));
}
.hero-stats>div{
  padding:26px 28px 28px;border-inline-end:1px solid var(--line);
  display:flex;flex-direction:column;gap:7px;
  transition:background .18s ease;
}
.hero-stats>div:last-child{border-inline-end:0;padding-inline-end:0}
.hero-stats>div:first-child{padding-inline-start:0}
.hero-stats>div:hover{background:var(--accent-soft)}
.hero-stats .v{
  font-family:var(--f-d);font-weight:700;font-size:1.06rem;letter-spacing:-.014em;
  display:flex;align-items:center;gap:9px;color:var(--fg);
}
.hero-stats .v .ar{color:var(--accent);transition:transform .2s ease}
.hero-stats>div:hover .v .ar{transform:translateX(4px)}
html[dir="rtl"] .hero-stats>div:hover .v .ar{transform:translateX(-4px)}
.hero-stats .l{
  font-family:var(--f-b);font-size:.87rem;letter-spacing:0;text-transform:none;
  color:var(--fg-3);margin-top:0;line-height:1.5;
}
@media (max-width:900px){
  .hero-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .hero-stats>div:nth-child(2n){border-inline-end:0}
  .hero-stats>div:nth-child(-n+2){border-bottom:1px solid var(--line)}
}
@media (max-width:560px){
  .hero-stats{grid-template-columns:1fr}
  .hero-stats>div{border-inline-end:0;border-bottom:1px solid var(--line)}
  .hero-stats>div:last-child{border-bottom:0}
}
html[dir="rtl"] .hero-stats .l{letter-spacing:.02em}
@media(max-width:820px){.hero-stats{flex-wrap:wrap}.hero-stats>div{flex:1 0 50%}}

/* ══════════ CAROUSEL ══════════
   One component, any mix of slide types. Transform driven rather than scroll
   driven, because scroll offsets invert in right-to-left and browsers disagree
   about the sign. */
.carousel{position:relative;overflow:hidden;background:var(--bg-2);border:1px solid var(--line)}
.carousel--bare{border:0;background:none}
.carousel-viewport{overflow:hidden}
.carousel-track{display:flex;transition:transform .55s cubic-bezier(.4,.01,.2,1);will-change:transform}
.carousel-track>*{flex:0 0 100%;min-width:0}
@media (prefers-reduced-motion: reduce){.carousel-track{transition:none}}

/* Controls sit in their own bar rather than floating over the slide, so they
   can never land on top of a headline at any width. */
.carousel-bar{
  display:flex;align-items:center;gap:14px;padding:12px 20px;
  border-top:1px solid var(--line);background:var(--bg);flex-wrap:wrap;
}
.carousel--bare .carousel-bar{background:none;border-top:0;padding-inline:0}
.carousel-dots{display:flex;gap:7px;align-items:center}
.carousel-dots button{
  width:28px;height:4px;border:0;padding:0;background:var(--line-2);cursor:pointer;
}
.carousel-dots button:hover{background:var(--fg-3)}
.carousel-dots button[aria-current="true"]{background:var(--accent)}
.carousel-count{font-family:var(--f-m);font-size:.65rem;color:var(--fg-3);font-variant-numeric:tabular-nums}
.carousel-pause{
  border:1px solid var(--line);background:none;color:var(--fg-3);cursor:pointer;font-family:var(--f-m);
  font-size:.58rem;letter-spacing:.09em;text-transform:uppercase;padding:5px 10px;
}
.carousel-pause:hover{color:var(--fg);border-color:var(--line-2)}
html[dir="rtl"] .carousel-pause,html[dir="rtl"] .carousel-count{letter-spacing:.02em}
.carousel-nav{margin-inline-start:auto;display:flex;gap:8px}
.carousel-ctrl{
  width:34px;height:34px;display:grid;place-items:center;
  background:var(--bg-2);border:1px solid var(--edge);color:var(--fg);cursor:pointer;
}
.carousel-ctrl:hover{border-color:var(--accent);color:var(--accent)}
.carousel-ctrl svg{width:12px;height:12px}
html[dir="rtl"] .carousel-ctrl svg{transform:scaleX(-1)}

/* ── slide types ── */
.slide{position:relative;display:flex;min-height:400px}
/* As a page hero rather than a section component.

   Sized so the hero, its pager and the four routes underneath fill the window
   and the section after them shows just enough to say the page continues. The
   subtraction is the chrome above and below the picture: the header, the pager
   strip, the routes band, and the sliver of the next section left on purpose.
   Clamped at both ends, because a laptop should not get a letterbox and a tall
   monitor should not get a slide you have to scroll past. */
.hero-v--carousel .slide{min-height:clamp(580px,calc(100vh - 320px),840px)}
@media (max-width:900px){.hero-v--carousel .slide{min-height:clamp(460px,calc(100vh - 300px),620px)}}
@media (max-width:600px){.hero-v--carousel .slide{min-height:420px}}
.slide--media{align-items:center;padding:0}
.slide-bg{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--bg-3)}
.slide-bg canvas,.slide-bg img,.slide-bg video{width:100%;height:100%;object-fit:cover;display:block}
/* The copy sits on the photograph, so the photograph has to get out of the way
   where the words are. The scrim used to run bottom upwards while the copy sat
   at mid height, which left a paragraph of grey text on a lit ceiling. Same
   treatment as the video hero now: near solid on the reading side, clear on the
   other, so the picture is still a picture. */
.slide-bg::after{content:"";position:absolute;inset:0;background:var(--scrim)}
html[dir="rtl"] .slide-bg::after{background:var(--scrim-rtl)}
@media (max-width:820px){
  .slide-bg::after,html[dir="rtl"] .slide-bg::after{background:var(--scrim-narrow)}
}
/* The copy has to sit on the same grid as the rest of the page. It was padded
   44px from the edge of a full bleed slide, so the heading started at the very
   left of the window while every other section on the page started at the wrap.
   It is a wrap of its own now, with the text constrained inside it. */
.slide-copy{
  position:relative;z-index:2;
  width:100%;max-width:var(--maxw);margin:0 auto;padding:52px 28px;
}
/* The heading has to wrap inside the readable side of the scrim, not run
   across the photograph. Two lines at this size is about twenty four
   characters; the body can take a little more. */
.slide-copy h1,.slide-copy h2,.slide-copy h3{max-width:20ch}
.slide-copy .eyeb,.slide-copy p{max-width:46ch}
@media (max-width:820px){
  .slide-copy h1,.slide-copy h2,.slide-copy h3,.slide-copy p{max-width:none}
}
@media (max-width:820px){.slide-copy{padding:34px 18px}}
.slide-copy .eyeb{font-family:var(--f-m);font-size:.62rem;letter-spacing:.13em;text-transform:uppercase;color:var(--accent);margin-bottom:12px;display:block}
html[dir="rtl"] .slide-copy .eyeb{letter-spacing:.03em}
.slide-copy h1,.slide-copy h2,.slide-copy h3{font-size:clamp(1.5rem,3.1vw,2.3rem);margin-bottom:14px;letter-spacing:-.025em;line-height:1.12}
/* Hero type, not component type. */
.hero-v--carousel .slide-copy h1,
.hero-v--carousel .slide-copy h2,
.hero-v--carousel .slide-copy h3{font-size:clamp(2rem,4.4vw,3.35rem);letter-spacing:-.032em;line-height:1.06;margin-bottom:18px}
.hero-v--carousel .slide-copy p{font-size:1.06rem;line-height:1.62;max-width:52ch}
.hero-v--carousel .slide-copy{padding:64px 28px}
.hero-v--carousel .slide-copy .btn{margin-top:28px;padding:13px 24px;font-size:.95rem}
@media (max-width:820px){.hero-v--carousel .slide-copy{padding:40px 18px}
  .hero-v--carousel .slide-copy p{font-size:.98rem}}
.slide-copy p{color:var(--fg-2);font-size:.95rem;max-width:56ch}
.slide-btns{display:flex;gap:12px;flex-wrap:wrap;margin-top:22px}
.slide-copy .btn{margin-top:0}

.slide--text{align-items:center;background:var(--bg-2)}
.slide--quote{align-items:center;background:var(--bg-3)}
.slide--quote blockquote{margin:0;font-family:var(--f-d);font-weight:600;font-size:clamp(1.2rem,2.5vw,1.75rem);line-height:1.4;letter-spacing:-.015em;max-width:24ch}
html[dir="rtl"] .slide--quote blockquote{letter-spacing:0;line-height:1.6}
.slide--quote .by{margin-top:20px;color:var(--fg-3);font-size:.86rem}

.slide--stats{align-items:center;background:var(--bg-2)}
.slide-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:28px;width:100%;padding:44px}
@media(max-width:820px){.slide-stats{grid-template-columns:repeat(2,1fr);gap:22px}}
.slide-stats .v{font-family:var(--f-d);font-weight:800;font-size:clamp(1.7rem,4vw,2.6rem);color:var(--accent);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.slide-stats .l{color:var(--fg-2);font-size:.86rem;margin-top:8px;max-width:22ch}

.slide--icons{align-items:center;background:var(--bg-2)}
.slide-icons{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);width:100%;border-block:1px solid var(--line)}
@media(max-width:820px){.slide-icons{grid-template-columns:repeat(2,1fr)}}
.slide-icons>div{background:var(--bg-2);padding:26px 22px}
.slide-icons svg{width:24px;height:24px;color:var(--accent);margin-bottom:14px}
.slide-icons h3{font-size:.98rem;margin-bottom:6px}
.slide-icons p{font-size:.82rem;color:var(--fg-3)}

.slide--product{align-items:center;background:var(--bg-2)}
.slide-product{display:grid;grid-template-columns:1fr 1fr;gap:0;width:100%;align-items:center}
@media(max-width:820px){.slide-product{grid-template-columns:1fr}}
.slide-product .copy{padding:44px}
.slide-product .shot{border-inline-start:1px solid var(--line);align-self:stretch;display:flex}
@media(max-width:820px){.slide-product .shot{border-inline-start:0;border-top:1px solid var(--line)}}

.pagehead{padding:66px 0 54px;border-bottom:1px solid var(--line);position:relative;overflow:hidden}
.pagehead h1{font-size:clamp(1.9rem,4.2vw,2.9rem);font-weight:800;max-width:19ch;margin-top:14px}
.pagehead .lede{margin-top:18px}
.crumb{color:var(--fg-3);display:flex;gap:9px;align-items:center;flex-wrap:wrap}
.crumb a{color:var(--accent)}

/* ══════════ STRIP ══════════ */
.strip{display:flex;background:var(--bg-3);border-bottom:1px solid var(--line)}
.strip>div{flex:1;padding:20px 26px;border-inline-end:1px solid var(--line);color:var(--fg-3)}
.strip>div:last-child{border-inline-end:0}
.strip b{display:block;font-family:var(--f-d);font-size:1.02rem;color:var(--fg);margin-bottom:3px;font-weight:600;letter-spacing:-.01em}
@media(max-width:820px){.strip{flex-wrap:wrap}.strip>div{flex:1 0 50%}}

/* ══════════ CARDS ══════════ */
.card{
  background:var(--bg-2);border:1px solid var(--line);padding:26px 24px 22px;
  display:flex;flex-direction:column;gap:10px;position:relative;
  transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease;
}
/* A rule that draws itself along the top edge on hover. It is the cheapest way
   to make a grid of eight cards feel like eight links rather than eight boxes. */
.card::after{
  content:"";position:absolute;top:-1px;inset-inline-start:-1px;height:2px;width:0;
  background:var(--accent);transition:width .28s ease;
}
.card:hover::after{width:calc(100% + 2px)}
.card h3{font-size:1.08rem;letter-spacing:-.012em}
.card h3,.card .card-h{font-size:1.08rem}
.card p{color:var(--fg-2);font-size:.91rem}
.card .lnk{margin-top:auto;padding-top:12px}
.card-hov:hover{border-color:var(--line-2);box-shadow:var(--shadow);transform:translateY(-3px)}

/* ══════════ CARD WITH A PICTURE ══════════
   For a listing where every record has its own photograph. The padding moves
   off the card and onto the body, so the picture runs to the edges. */
.card--media{padding:0;overflow:hidden}
.card-media{aspect-ratio:16/9;overflow:hidden;background:var(--bg-3);flex:none}
/* A document cover is portrait by nature, so it gets a squarer window than a
   photograph does and is not cropped to a letterbox. */
.card-media--tall{aspect-ratio:3/2}
.card-media img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .5s ease}
.card--media:hover .card-media img{transform:scale(1.04)}
.card-body{padding:22px 22px 20px;display:flex;flex-direction:column;gap:9px;flex:1}
.card--media .lnk{margin-top:auto;padding-top:14px}


.pcard{
  background:var(--bg-2);border:1px solid var(--line);padding:0;position:relative;
  display:flex;flex-direction:column;overflow:hidden;
  transition:box-shadow .2s ease,transform .2s ease,border-color .2s ease;
}
.pcard::before{content:"";position:absolute;top:0;inset-inline-start:0;width:100%;height:3px;background:var(--p);z-index:3}
.pcard:hover{box-shadow:var(--shadow);transform:translateY(-3px);border-color:var(--line-2)}

/* the cover, across the whole card rather than a square in the header row */
.pcard .cover{position:relative;aspect-ratio:16/10;overflow:hidden;background:var(--bg-3);flex:none}
.pcard .cover img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .5s ease}
.pcard:hover .cover img{transform:scale(1.035)}
.pcard .cover::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 45%,color-mix(in srgb,var(--bg-2) 88%,transparent) 100%);
}

/* A screen from the product itself, rather than a photograph.

   Shown whole, a 1560 pixel wide interface inside a 380 pixel card is a grey
   smudge: it reads as "an image was required here", which is what was wrong
   with the photographs. Cropped into its top corner at about half size, the
   product's own navigation, page title and headline figures stay legible, and
   the card says what the software is before a word is read.

   The crop is anchored to the physical left in both directions, because the
   interface in the picture is laid out left to right whichever way the page
   around it runs. */
.pcard .cover--screen{background:var(--bg-2)}
.pcard .cover--screen img{
  position:absolute;top:0;left:0;width:190%;height:auto;max-width:none;
  object-fit:none;transform:none;
}
.pcard:hover .cover--screen img{transform:none}
/* The fade has to carry further than it does over a photograph. An interface
   is mostly pale, so a gradient tuned to it leaves the dark navigation column
   ending in a hard horizontal cut halfway down the card. */
.pcard .cover--screen::after{
  background:linear-gradient(180deg,
    transparent 26%,
    color-mix(in srgb,var(--bg-2) 55%,transparent) 66%,
    var(--bg-2) 97%);
}
@media (max-width:960px){
  /* Two up, so each card is wider and the crop can pull back a little. */
  .pcard .cover--screen img{width:150%}
}

/* the mark sits on the bottom edge of the cover, which ties the two together */
.pcard .plogo{
  width:54px;height:54px;border-radius:13px;padding:10px;margin:-52px 0 4px;
  position:relative;z-index:2;
  background:var(--bg-2);box-shadow:0 8px 22px -10px rgba(10,18,35,.5);
}
.pcard .body{padding:24px;display:flex;flex-direction:column;gap:11px;flex:1}
.pcard .top{display:flex;flex-direction:column;gap:3px}

/* Product logomarks. The mark is drawn at whatever size its slot asks for, and
   an uploaded logo is an image in the same slot, so the two are interchangeable
   without the layout knowing which it got. */
/* A block of running text wants a reading measure, but it should still start
   on the same edge as the section above it rather than float in the middle. */
.entry-measure{max-width:72ch}
/* A card is a flex column, so a button inside it stretches to the full width
   unless told not to. A call to action should be the size of its label. */
.card .btn{align-self:flex-start}
/* An underline on hover belongs on a link inside a sentence, not on a menu
   entry, a dropdown row or a whole card, where the underline lands under
   several lines of unrelated text and reads as a fault. */
.entry a:not(.btn):not(.lnk){text-decoration:underline;text-underline-offset:2px}
.entry a:not(.btn):not(.lnk):hover{text-decoration-thickness:2px}
a:hover,a:focus{text-decoration:none}
.entry a:not(.btn):not(.lnk):hover,.entry a:not(.btn):not(.lnk):focus{text-decoration:underline}
/* The menu button is a hamburger, and the language switcher wears a globe, so
   neither costs a word of width on a phone. The close icon replaces the
   hamburger while the menu is open, which is what people expect. */
.burger{align-items:center;justify-content:center;padding:7px 9px;line-height:0}
.burger svg{display:block;color:currentColor}
.burger .burger-close{display:none}
.burger[aria-expanded="true"] .burger-open{display:none}
.burger[aria-expanded="true"] .burger-close{display:block}
.seg--lang{align-items:center}
.seg-icon{display:inline-flex;align-items:center;padding:0 8px;color:var(--fg-3);border-inline-end:1px solid var(--edge)}
.seg-icon svg{display:block}
/* Heading levels follow the document outline, not the type scale. A card
   title is an h2 when it sits directly under the page title and an h3 when
   it sits inside a section; either way it is the same size on screen. */
.card-h{font-size:1.08rem;font-weight:700;letter-spacing:-.021em}
.foot-h{font-weight:700}
.plogo{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;line-height:0}
.plogo svg,.plogo img{display:block;width:100%;height:100%;object-fit:contain}
.plogo-sm{width:40px;height:40px}
.plogo-lg{width:64px;height:64px;margin-bottom:20px}
.plogo .on-dark{display:none}
@media(prefers-color-scheme:dark){
 :root:not([data-theme="light"]) .plogo .on-light{display:none}
 :root:not([data-theme="light"]) .plogo .on-dark{display:block}
}
:root[data-theme="dark"] .plogo .on-light{display:none}
:root[data-theme="dark"] .plogo .on-dark{display:block}
/* The banner of a product page sits in that product's colour rather than the
   site's, so the whole view reads as that product. */
.p-hero .plogo-lg{margin-bottom:22px}
.pcard .pname{transition:color .16s ease}
.pcard:hover .pname{color:var(--p)}
.pcard .pname{font-family:var(--f-d);font-weight:800;font-size:1.5rem;letter-spacing:-.024em;line-height:1.12}
.pcard .pcat{font-family:var(--f-m);font-size:.62rem;letter-spacing:.11em;text-transform:uppercase;color:var(--p)}
html[dir="rtl"] .pcard .pcat{letter-spacing:.02em}
.pcard p{color:var(--fg-2);font-size:.91rem}
.pcard .tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.pcard .tags span{font-size:.72rem;color:var(--fg-3);background:var(--bg);border:1px solid var(--line);padding:4px 9px;border-radius:3px}
.pcard .go{margin-top:auto;padding-top:16px;color:var(--p);font-family:var(--f-m);font-size:.7rem;letter-spacing:.09em;text-transform:uppercase;display:flex;gap:7px;align-items:center}
.pcard .go .ar{transition:transform .2s ease}
.pcard:hover .go .ar{transform:translateX(4px)}
html[dir="rtl"] .pcard:hover .go .ar{transform:translateX(-4px)}
.pcard--ghost .body{padding:24px}
html[dir="rtl"] .pcard .go{letter-spacing:.02em}
.pcard--ghost{border-style:dashed;align-items:center;justify-content:center;text-align:center;color:var(--fg-3);min-height:190px;gap:8px}
.pcard--ghost::before{display:none}

.split{display:grid;grid-template-columns:1fr 1fr;border:1px solid var(--line);background:var(--bg-2)}
@media(max-width:780px){.split{grid-template-columns:1fr}}
.split>div{padding:34px}
.split>div:first-child{border-inline-end:1px solid var(--line)}
@media(max-width:780px){.split>div:first-child{border-inline-end:0;border-bottom:1px solid var(--line)}}
.split .num{font-family:var(--f-m);font-size:.68rem;letter-spacing:.13em;color:var(--accent);display:block;margin-bottom:14px}
.split h3{font-size:1.3rem;margin-bottom:12px}
.split p{color:var(--fg-2);font-size:.94rem}
.split ul{margin-top:18px;display:flex;flex-direction:column;gap:7px}
.split li{color:var(--fg-2);font-size:.9rem;display:flex;gap:10px;align-items:flex-start}
.split li::before{content:"";width:5px;height:5px;background:var(--accent);flex:none;margin-top:8px}

/* The tiles were a hairline table: twenty four pixel padding, a one pixel
   gutter and eight cells of small grey text. Separate cards with real gutters
   read as choices instead of as a spreadsheet. */
.tiles{display:grid;grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));gap:14px;background:none;border:0}
@media(max-width:980px){.tiles{grid-template-columns:repeat(2,minmax(0,1fr))!important}}
@media(max-width:560px){.tiles{grid-template-columns:1fr}}
.tile{
  background:var(--bg-2);border:1px solid var(--line);padding:24px 22px 22px;
  display:flex;flex-direction:column;gap:8px;min-height:172px;position:relative;
  transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease;
}
.tile:hover{border-color:var(--line-2);box-shadow:var(--shadow);transform:translateY(-3px)}
.tile:hover{background:var(--bg-3)}
.tile .n{
  font-family:var(--f-m);font-size:.66rem;color:var(--accent);letter-spacing:.1em;
  padding-bottom:9px;margin-bottom:2px;border-bottom:1px solid var(--line);
}
.tile h3{font-size:1.04rem;font-weight:650;letter-spacing:-.012em;line-height:1.25}
.tile p{font-size:.86rem;color:var(--fg-2);line-height:1.55}

.eng{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line)}
@media(max-width:760px){.eng{grid-template-columns:1fr}}
.eng a{background:var(--bg-2);padding:20px 24px;display:grid;grid-template-columns:34px 1fr;gap:16px;align-items:baseline}
.eng a:hover{background:var(--bg-3)}
.eng .n{font-family:var(--f-m);font-size:.7rem;color:var(--accent);font-variant-numeric:tabular-nums}
.eng h3{font-size:1rem;font-weight:600;margin-bottom:4px}
.eng p{font-size:.85rem;color:var(--fg-2)}
.eng .k{font-family:var(--f-m);font-size:.58rem;letter-spacing:.11em;text-transform:uppercase;color:var(--fg-3);display:inline-block;margin-top:9px;border:1px solid var(--line);padding:3px 8px}
html[dir="rtl"] .eng .k{letter-spacing:.02em}

/* Twelve solution areas. As a wrapped row of pills this read as a tag cloud
   and gave no sense that each one is a page worth opening. As a grid of rows
   with an accent edge and an arrow, it reads as a menu. */
.chips{display:grid;grid-template-columns:repeat(var(--cols,3),minmax(0,1fr));gap:12px}
.chips--spaced{margin-top:14px}
.chips--spaced-lg{margin-top:26px}
.chip{
  position:relative;border:1px solid var(--line);background:var(--bg-2);
  padding:17px 40px 17px 19px;font-size:.95rem;color:var(--fg);
  display:flex;align-items:center;min-height:60px;line-height:1.35;
  transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease;
}
.chip::before{
  content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:3px;
  background:var(--accent);opacity:0;transition:opacity .18s ease;
}
.chip::after{
  content:"→";position:absolute;inset-inline-end:16px;color:var(--accent);
  font-size:.95rem;opacity:.45;transition:opacity .18s ease,transform .18s ease;
}
html[dir="rtl"] .chip{padding:17px 19px 17px 40px}
html[dir="rtl"] .chip::after{content:"←"}
.chip:hover{border-color:var(--line-2);box-shadow:var(--shadow);transform:translateY(-2px)}
.chip:hover::before{opacity:1}
.chip:hover::after{opacity:1;transform:translateX(3px)}
html[dir="rtl"] .chip:hover::after{transform:translateX(-3px)}
@media (max-width:900px){.chips{grid-template-columns:repeat(2,minmax(0,1fr))!important}}
@media (max-width:560px){.chips{grid-template-columns:1fr!important}}

.quote{border:1px solid var(--line);background:var(--bg-2);padding:38px}
.quote blockquote{margin:0;font-family:var(--f-d);font-size:1.25rem;line-height:1.42;font-weight:600;letter-spacing:-.015em}
html[dir="rtl"] .quote blockquote{letter-spacing:0;line-height:1.6}
.quote .by{margin-top:20px;color:var(--fg-3);font-size:.86rem}

/* The action sits opposite the heading rather than under it, so the band
   uses its width instead of leaving half of itself empty. */
.cta{background:var(--accent);color:var(--accent-fg);padding:56px 0;position:relative;overflow:hidden}
.cta > .wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:40px;align-items:center}
.cta h2{font-size:clamp(1.55rem,2.9vw,2.05rem);max-width:22ch;line-height:1.14}
.cta p{margin-top:10px;opacity:.9;max-width:54ch}
.cta .btns{margin-top:0;display:flex;gap:12px;flex-wrap:wrap;flex:none}

/* A large, very quiet mark in the corner, so the band is not a flat rectangle. */
.cta::after{
  content:"";position:absolute;inset-inline-end:-90px;top:50%;transform:translateY(-50%);
  width:330px;height:330px;border-radius:50%;
  background:radial-gradient(circle at 35% 35%, rgba(255,255,255,.16), transparent 62%);
  pointer-events:none;
}
@media (max-width:860px){
  .cta > .wrap{grid-template-columns:1fr;gap:24px}
  .cta .btns{margin-top:4px}
  .cta::after{display:none}
}
.cta .btn-w{background:var(--accent-fg);color:var(--accent)}
.cta .btn-t{border-color:currentColor;color:var(--accent-fg);background:none}

/* ══════════ ARTICLE LIST ══════════ */
.rows{border-top:1px solid var(--line)}
/* The rows were three columns of small type on a hairline. Giving the middle
   column real weight, and the whole row a hover state and a little inset,
   turns a list into something you can see is clickable. */
.row{
  display:grid;grid-template-columns:150px 1fr 130px;gap:28px;
  padding:24px 20px;margin-inline:-20px;border-bottom:1px solid var(--line);
  align-items:baseline;transition:background .16s ease;
}
.row:hover{background:var(--bg-2)}
.row:hover h2,.row:hover h3{color:var(--accent)}
/* The row bleeds twenty pixels past the wrap so its hover state reaches the
   edge of the text. On a phone the wrap only has eighteen pixels of padding to
   bleed into, so it hung two pixels off the side of the page and put a
   horizontal scrollbar on every listing. */
@media(max-width:780px){.row{grid-template-columns:1fr;gap:6px;margin-inline:-18px;padding-inline:18px}}
.row .k{font-family:var(--f-m);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--accent)}
html[dir="rtl"] .row .k{letter-spacing:.02em}
.row h2,.row h3{font-size:1.18rem;margin-bottom:7px;letter-spacing:-.016em;transition:color .16s ease}
.row p{color:var(--fg-2);font-size:.91rem;max-width:66ch;line-height:1.6}
.row .d{color:var(--fg-3);font-size:.8rem;font-family:var(--f-m);text-align:end}
@media(max-width:780px){.row .d{text-align:start}}

/* A row that carries a picture: thumbnail, copy, date. Used on the insights
   index, where six rows of plain text sat on a page about a visual product. */
.row--media{grid-template-columns:190px 1fr 130px;align-items:center}
.row-thumb{display:block;aspect-ratio:16/10;overflow:hidden;background:var(--bg-3);border:1px solid var(--line)}
.row-thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .5s ease}
.row--media:hover .row-thumb img{transform:scale(1.04)}
.row--media .k{display:block;margin-bottom:7px}
/* The same row with the picture at the end rather than the start, for a
   listing whose last column would otherwise be empty: an illustrative scenario
   has no client to name there. */
.row--tail{grid-template-columns:150px 1fr 210px;align-items:center}
/* A row with nothing in its last column, which is what a search result is,
   closes the column up rather than reserving a hundred and thirty pixels for
   a date that is not coming. */
.row:not(:has(> .d)):not(:has(> .row-thumb)){grid-template-columns:150px minmax(0,1fr)}
@media (max-width:780px){
  .row--media,.row--tail{grid-template-columns:1fr;gap:12px}
  .row-thumb{max-width:320px}
}


/* ══════════ PRODUCT PAGE ══════════ */
.p-hero{position:relative;overflow:hidden;padding:70px 0 60px;border-bottom:1px solid var(--line);background:var(--bg-2)}
.p-hero .badge{display:inline-flex;align-items:center;gap:9px;border:1px solid var(--p);color:var(--p);padding:6px 12px;font-family:var(--f-m);font-size:.64rem;letter-spacing:.1em;text-transform:uppercase}
html[dir="rtl"] .p-hero .badge{letter-spacing:.02em}
.p-hero .pwordmark{display:flex;align-items:center;gap:14px;margin:26px 0 20px}
.p-hero .pwordmark .nm{font-family:var(--f-d);font-weight:800;font-size:2.6rem;letter-spacing:-.03em;line-height:1}
.p-hero h1{font-size:clamp(1.65rem,3.6vw,2.5rem);max-width:20ch}
.p-hero .lede{margin-top:18px}
.p-hero .btns{display:flex;gap:12px;margin-top:30px;flex-wrap:wrap}
.p-arcs{position:absolute;inset-inline-end:-140px;top:-100px;width:520px;height:520px;opacity:.35;pointer-events:none;color:var(--p)}
.subnav{position:sticky;top:70px;z-index:40;background:var(--bg);border-bottom:1px solid var(--line);overflow-x:auto}
.subnav .in{display:flex;gap:0;max-width:var(--maxw);margin:0 auto;padding:0 28px;min-width:max-content}
.subnav a{padding:15px 18px;font-family:var(--f-m);font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;color:var(--fg-3);border-bottom:2px solid transparent}
html[dir="rtl"] .subnav a{letter-spacing:.02em}
.subnav a:hover{color:var(--fg)}
.subnav a.on{color:var(--p);border-bottom-color:var(--p)}
.p-metrics{display:flex;background:var(--bg-3);border-bottom:1px solid var(--line)}
.p-metrics>div{flex:1;padding:22px 26px;border-inline-end:1px solid var(--line)}
.p-metrics>div:last-child{border-inline-end:0}
.p-metrics .v{font-family:var(--f-d);font-weight:800;font-size:1.5rem;color:var(--p);letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.p-metrics .l{font-family:var(--f-m);font-size:.62rem;letter-spacing:.11em;text-transform:uppercase;color:var(--fg-3);margin-top:5px}
html[dir="rtl"] .p-metrics .l{letter-spacing:.02em}
@media(max-width:780px){.p-metrics{flex-wrap:wrap}.p-metrics>div{flex:1 0 50%}}
.probs{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:820px){.probs{grid-template-columns:1fr}}
.prob{border:1px solid var(--line);background:var(--bg-2);padding:26px;border-top:3px solid var(--p)}
.prob h3{font-size:1.04rem;margin-bottom:9px}
.prob p{color:var(--fg-2);font-size:.9rem}
/* Real gutters, not a one pixel gap over a coloured container. The old
   technique painted the container behind the grid, so six capabilities in a
   four column grid left two grey rectangles that looked like missing content. */
.caps{display:grid;grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));gap:14px;background:none;border:0}
@media(max-width:980px){.caps{grid-template-columns:repeat(2,minmax(0,1fr))!important}}
@media(max-width:560px){.caps{grid-template-columns:1fr!important}}
.cap{
  background:var(--bg-2);border:1px solid var(--line);padding:24px 22px;min-height:172px;
  transition:border-color .18s ease,box-shadow .18s ease,transform .18s ease;
}
.cap:hover{border-color:var(--line-2);box-shadow:var(--shadow);transform:translateY(-3px)}
.cap .ic{
  width:38px;height:38px;padding:8px;border-radius:9px;margin-bottom:14px;
  color:var(--p);background:color-mix(in srgb,var(--p) 10%,transparent);
}
.cap h3{font-size:1.04rem;font-weight:650;margin-bottom:7px;letter-spacing:-.012em}
.cap p{font-size:.87rem;color:var(--fg-2);line-height:1.55}
.mods{border:1px solid var(--line);background:var(--bg-2)}
.mod{display:grid;grid-template-columns:170px 1fr;gap:22px;padding:20px 26px;border-bottom:1px solid var(--line)}
.mod:last-child{border-bottom:0}
@media(max-width:680px){.mod{grid-template-columns:1fr;gap:6px}}
.mod h3{font-size:1rem}
.mod p{color:var(--fg-2);font-size:.89rem}
.faq{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{padding:20px 0;font-family:var(--f-d);font-weight:600;font-size:1.02rem;cursor:pointer;list-style:none;display:flex;gap:16px;align-items:flex-start}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";margin-inline-start:auto;color:var(--p);font-family:var(--f-m);font-size:1.2rem;line-height:1}
.faq details[open] summary::after{content:"–"}
.faq .a{padding:0 0 22px;color:var(--fg-2);font-size:.93rem;max-width:70ch}
.screens{border:1px solid var(--line);background:var(--bg-3);padding:0;overflow:hidden}
.screens .bar{display:flex;gap:7px;align-items:center;padding:11px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}
.screens .dot{width:9px;height:9px;border-radius:50%;background:var(--line-2)}
.screens .lbl{font-family:var(--f-m);font-size:.66rem;color:var(--fg-3);margin-inline-start:8px}
.appshot{display:grid;grid-template-columns:190px 1fr;min-height:330px}
@media(max-width:680px){.appshot{grid-template-columns:1fr}.appshot .side{display:none}}
.appshot .side{background:var(--bg-2);border-inline-end:1px solid var(--line);padding:18px 0}
.appshot .side .it{padding:9px 18px;font-size:.82rem;color:var(--fg-3);display:flex;gap:10px;align-items:center}
.appshot .side .it.on{color:var(--p);background:var(--bg-3);border-inline-start:2px solid var(--p)}
.appshot .side .it i{width:6px;height:6px;background:currentColor;display:block;flex:none}
.appshot .main{padding:20px;display:flex;flex-direction:column;gap:14px;background:var(--bg-2)}
.appshot .toolbar{display:flex;gap:10px;align-items:center}
.appshot .pillbtn{font-family:var(--f-m);font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;padding:6px 11px;border:1px solid var(--line);color:var(--fg-3)}
.appshot .pillbtn.on{background:var(--p);color:var(--p-fg);border-color:var(--p)}
.appshot table{width:100%;border-collapse:collapse;font-size:.8rem}
.appshot th{font-family:var(--f-m);font-size:.6rem;letter-spacing:.09em;text-transform:uppercase;color:var(--fg-3);text-align:start;padding:9px 10px;border-bottom:1px solid var(--line);font-weight:500}
.appshot td{padding:11px 10px;border-bottom:1px solid var(--line);color:var(--fg-2)}
.appshot td b{color:var(--fg);font-weight:600}
.st{font-family:var(--f-m);font-size:.58rem;letter-spacing:.07em;text-transform:uppercase;padding:3px 8px;white-space:nowrap}
.st-a{background:var(--accent-soft);color:var(--accent)}
.st-b{background:rgba(138,102,32,.14);color:var(--brass)}
.st-c{background:rgba(17,107,69,.13);color:var(--good)}
html[dir="rtl"] .st,html[dir="rtl"] .appshot .pillbtn,html[dir="rtl"] .appshot th{letter-spacing:.01em}

/* ══════════ CMS ADMIN MOCKUP ══════════ */
.wp{display:grid;grid-template-columns:190px 1fr;border:1px solid var(--line);background:var(--bg-2);overflow:hidden}
@media(max-width:820px){.wp{grid-template-columns:1fr}.wp-side{display:none}}
.wp-side{background:var(--bg-3);border-inline-end:1px solid var(--line);padding:14px 0}
.wp-side .grp{font-family:var(--f-m);font-size:.58rem;letter-spacing:.12em;text-transform:uppercase;color:var(--fg-3);padding:14px 16px 6px}
html[dir="rtl"] .wp-side .grp{letter-spacing:.02em}
.wp-side .it{padding:8px 16px;font-size:.83rem;color:var(--fg-2);display:flex;gap:9px;align-items:center}
.wp-side .it.on{background:var(--accent);color:var(--accent-fg);font-weight:600}
.wp-side .it i{width:5px;height:5px;background:currentColor;flex:none;display:block}
.wp-main{padding:22px;display:flex;flex-direction:column;gap:16px;min-width:0}
.wp-title{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.wp-title h3{font-size:1.2rem}
.wp-title .badge{font-family:var(--f-m);font-size:.58rem;letter-spacing:.1em;text-transform:uppercase;border:1px solid var(--line-2);color:var(--fg-3);padding:3px 8px}
.wp-cols{display:grid;grid-template-columns:1fr 250px;gap:16px;align-items:start}
@media(max-width:900px){.wp-cols{grid-template-columns:1fr}}
.mb{border:1px solid var(--line);background:var(--bg)}
.mb>h3{font-size:.86rem;font-weight:600;padding:11px 15px;border-bottom:1px solid var(--line);background:var(--bg-3);display:flex;align-items:center;gap:9px}
.mb>h3 .req{font-family:var(--f-m);font-size:.56rem;letter-spacing:.09em;text-transform:uppercase;color:var(--accent);margin-inline-start:auto}
html[dir="rtl"] .mb>h3 .req{letter-spacing:.02em}
.mb .in{padding:15px;display:flex;flex-direction:column;gap:14px}
.fr{display:grid;grid-template-columns:150px 1fr;gap:14px;align-items:start}
@media(max-width:640px){.fr{grid-template-columns:1fr;gap:5px}}
.fr>label{font-size:.79rem;color:var(--fg-2);padding-top:8px;font-weight:500}
.fr>label small{display:block;color:var(--fg-3);font-size:.71rem;font-weight:400;margin-top:2px}
.inp{border:1px solid var(--line-2);background:var(--bg-2);padding:8px 11px;font-size:.83rem;color:var(--fg);min-height:36px;display:flex;align-items:center}
.inp.ph{color:var(--fg-3)}
.inp.ta{min-height:60px;align-items:flex-start;line-height:1.5}
.sel{border:1px solid var(--line-2);background:var(--bg-2);padding:8px 11px;font-size:.83rem;display:flex;align-items:center;gap:8px}
.sel::after{content:"▾";margin-inline-start:auto;color:var(--fg-3)}
.upl{border:1px dashed var(--line-2);background:var(--bg-2);padding:12px;display:flex;gap:14px;align-items:center}
.upl .thumb{width:74px;height:44px;border:1px solid var(--line);background:var(--bg-3);display:grid;place-items:center;flex:none;overflow:hidden}
.upl .thumb.dark{background:#02071A}
.upl .thumb img{max-width:88%;max-height:78%;width:auto;display:block}
.upl .meta{min-width:0}
.upl .meta b{display:block;font-size:.79rem;font-weight:600}
.upl .meta span{font-size:.72rem;color:var(--fg-3)}
.upl .act{margin-inline-start:auto;display:flex;gap:7px;flex:none}
.mini{font-family:var(--f-m);font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--line-2);padding:6px 10px;color:var(--fg-2);white-space:nowrap}
.mini.pri{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}
html[dir="rtl"] .mini{letter-spacing:.02em}
.upl.empty{justify-content:center;text-align:center;flex-direction:column;gap:8px;color:var(--fg-3);padding:18px}
.colorpick{display:flex;align-items:center;gap:10px}
.colorpick .sw{width:34px;height:34px;border:1px solid var(--line-2);flex:none}
.rep{border:1px solid var(--line);background:var(--bg-2)}
.rep .rw{display:grid;grid-template-columns:26px 1fr auto;gap:12px;padding:10px 12px;border-bottom:1px solid var(--line);align-items:center;font-size:.8rem}
.rep .rw:last-child{border-bottom:0}
.rep .rw .h{font-family:var(--f-m);font-size:.62rem;color:var(--fg-3)}
.rep .rw b{font-weight:600}
.rep .rw p{color:var(--fg-3);font-size:.74rem}
.rep .add{padding:9px 12px;border-top:1px solid var(--line);color:var(--accent);font-family:var(--f-m);font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;background:var(--bg-3)}
html[dir="rtl"] .rep .add{letter-spacing:.02em}
.taxbox{display:flex;flex-direction:column;gap:7px;font-size:.81rem}
.taxbox span{display:flex;gap:9px;align-items:center;color:var(--fg-2)}
.taxbox i{width:13px;height:13px;border:1px solid var(--line-2);display:block;flex:none;position:relative;background:var(--bg-2)}
.taxbox i.ck{background:var(--accent);border-color:var(--accent)}
.taxbox i.ck::after{content:"";position:absolute;inset-inline-start:3px;top:1px;width:4px;height:7px;border:solid var(--accent-fg);border-width:0 2px 2px 0;transform:rotate(42deg)}
.pubrow{display:flex;justify-content:space-between;font-size:.79rem;padding:7px 0;border-bottom:1px solid var(--line);color:var(--fg-2)}
.pubrow:last-of-type{border-bottom:0}

/* ══════════ FORM ══════════ */
.form{background:var(--bg-2);border:1px solid var(--line);padding:32px}
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:18px}
.field label{font-family:var(--f-m);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-3)}
html[dir="rtl"] .field label{letter-spacing:.02em}
.field input,.field select,.field textarea{
  background:var(--bg);border:1px solid var(--edge);color:var(--fg);padding:12px 14px;font:400 .93rem/1.5 var(--f-b);font-family:inherit;width:100%;
}
.field textarea{min-height:120px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);outline:none}
.ctxnote{background:var(--accent-soft);border-inline-start:3px solid var(--accent);padding:12px 16px;font-size:.85rem;color:var(--fg-2);margin-bottom:20px}
.ctxnote b{color:var(--fg)}
.formrow{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media(max-width:600px){.formrow{grid-template-columns:1fr}}

/* ══════════ BANNER SHOWCASE ══════════ */
.showcase{padding:56px 0 0;border-bottom:1px solid var(--line)}
.showcase-head{display:grid;grid-template-columns:44px 1fr 240px;gap:24px;align-items:start}
@media(max-width:900px){.showcase-head{grid-template-columns:36px 1fr;gap:16px}}
.showcase-n{font-family:var(--f-m);font-size:.72rem;color:var(--accent);padding-top:7px}
.showcase-title h2{font-size:clamp(1.3rem,2.6vw,1.75rem);margin-bottom:10px}
.showcase-title p{color:var(--fg-2);font-size:.93rem;max-width:60ch}
.showcase-spec{margin:0;display:flex;flex-direction:column;gap:7px;border-inline-start:1px solid var(--line);padding-inline-start:20px}
@media(max-width:900px){.showcase-spec{grid-column:2;border-inline-start:0;padding-inline-start:0;padding-top:8px}}
.showcase-spec>div{display:flex;gap:10px;font-size:.79rem}
.showcase-spec dt{font-family:var(--f-m);font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3);width:96px;flex:none}
html[dir="rtl"] .showcase-spec dt{letter-spacing:.02em}
.showcase-spec dd{margin:0;color:var(--fg)}
.showcase-best{margin:18px 0 26px;padding-inline-start:20px;border-inline-start:3px solid var(--accent);color:var(--fg-2);font-size:.9rem;max-width:72ch}
.showcase-best b{color:var(--fg);font-weight:600}
.showcase-frame{border-block:1px solid var(--line);background:var(--bg-2)}
/* the catalogue shows a lot of banners at once, so each is shown shorter than
   it would run on a real page */
.showcase-frame .hero-v--video{padding:66px 0 58px}
.showcase-frame .hero-v--centred{padding:76px 0 68px}
.showcase-frame .hero-v--gradient{padding:70px 0 62px}
.showcase-frame .hero-v--minimal{padding:62px 0 56px}
.showcase-frame .hero-split-copy{padding:56px 0 52px;padding-inline-end:48px}
.showcase-frame .hero-split-media{min-height:340px}
.showcase-frame .hero-v h1{font-size:clamp(1.6rem,3.4vw,2.5rem)}
.showcase-frame .slide{min-height:340px}
.showcase .lnk{display:inline-flex;padding:18px 0 26px}

/* ══════════ LEGAL ══════════ */
.legal-sec{padding:26px 0;border-bottom:1px solid var(--line)}
.legal-sec h3{font-size:1.12rem;margin-bottom:12px}
.legal-sec p{color:var(--fg-2);font-size:.94rem;margin-bottom:12px;max-width:68ch}
.legal-sec p:last-child{margin-bottom:0}
.legal-sec .tbl-wrap{margin-top:14px}
.callout-legal{border-inline-start:3px solid var(--brass);background:var(--brass-soft,rgba(138,102,32,.09));padding:18px 22px;margin-top:34px}
.callout-legal p{color:var(--fg-2);font-size:.9rem;margin-top:8px;max-width:68ch}

/* ══════════ COOKIE BANNER ══════════ */
.cookiebar{
  position:fixed;inset-inline:0;bottom:0;z-index:90;background:var(--bg-2);
  border-top:1px solid var(--line-2);box-shadow:var(--shadow);
}
.cookiebar .in{max-width:var(--maxw);margin:0 auto;padding:18px 28px;display:flex;gap:20px;align-items:center;flex-wrap:wrap}
.cookiebar p{color:var(--fg-2);font-size:.88rem;flex:1;min-width:260px;max-width:62ch}
.cookiebar p b{color:var(--fg)}
.cookiebar .acts{display:flex;gap:10px;flex-wrap:wrap}
@media(max-width:560px){.cookiebar .in{padding:16px 20px}.cookiebar .acts{width:100%}.cookiebar .acts .btn{flex:1;justify-content:center}}

/* ══════════ FOOTER ══════════ */
footer.site{background:var(--bg-3);border-top:1px solid var(--line);padding:60px 0 0}
.fgrid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr 1fr;gap:32px}
@media(max-width:900px){.fgrid{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.fgrid{grid-template-columns:1fr}}
.fgrid .foot-h{font-family:var(--f-m);font-size:.64rem;letter-spacing:.13em;text-transform:uppercase;color:var(--fg-3);margin-bottom:14px;font-weight:500}
html[dir="rtl"] .fgrid .foot-h{letter-spacing:.03em}
.fgrid li{margin-bottom:8px}
.fgrid a{color:var(--fg-2);font-size:.88rem}
.fgrid a:hover{color:var(--accent)}
.fbrand p{color:var(--fg-3);font-size:.88rem;margin-top:14px;max-width:34ch}
.fbot{border-top:1px solid var(--line);margin-top:48px;padding:22px 0;display:flex;gap:18px;flex-wrap:wrap;color:var(--fg-3);font-size:.82rem}
.fbot .spacer{margin-inline-start:auto}

.protobar{background:var(--brass);color:#150E02;font-family:var(--f-m);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;padding:8px 0}
.protobar .wrap{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.proto-heroes{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.proto-heroes button{
  font-family:var(--f-m);font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;
  border:1px solid rgba(21,14,2,.35);background:rgba(255,255,255,.28);color:#150E02;
  padding:4px 9px;cursor:pointer;
}
.proto-heroes button[aria-pressed="true"]{background:#150E02;color:var(--brass);border-color:#150E02}
html[dir="rtl"] .proto-heroes button{letter-spacing:.02em}
html[dir="rtl"] .protobar{letter-spacing:.01em}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ══════════ WORDPRESS ══════════
   Everything above is generated from the design prototype. Do not edit it here.
   Rules below exist only because WordPress renders things the prototype has no
   equivalent for. */

.skip-link{
  position:absolute;inset-inline-start:-9999px;top:0;z-index:200;
  background:var(--accent);color:var(--accent-fg);padding:12px 20px;
  font:600 .9rem/1 var(--f-b);
}
.skip-link:focus{inset-inline-start:0}

.screen-reader-text{
  border:0;clip-path:inset(50%);height:1px;width:1px;margin:-1px;
  overflow:hidden;padding:0;position:absolute;white-space:nowrap;
}

.admin-bar header.site{top:32px}
@media screen and (max-width:782px){.admin-bar header.site{top:46px}}

/* Block editor content inside a page */
.entry{max-width:68ch}
.entry > * + *{margin-top:1.1em}
.entry h2{font-size:clamp(1.5rem,3vw,2.1rem);margin-top:1.8em}
.entry h3{font-size:1.25rem;margin-top:1.6em}
.entry p,.entry li{color:var(--fg-2)}
.entry ul,.entry ol{padding-inline-start:1.3em}
.entry ul{list-style:disc}
.entry ol{list-style:decimal}
.entry blockquote{
  border-inline-start:3px solid var(--accent);padding-inline-start:20px;
  font-family:var(--f-d);font-size:1.15rem;font-weight:600;
}
.entry img{height:auto}
.entry .alignwide{max-width:1240px}

/* A page of prose, run as headings down one column and their paragraphs down
   the other. The About page was four headings and four paragraphs in a column
   ending halfway across an otherwise empty page; this uses the width without
   making the reading measure any longer.

   Grid auto placement does the work: a heading is told to sit in the first
   column and everything else in the second, and because placement never
   backtracks, a heading following two paragraphs correctly starts a new row
   rather than sliding up beside the second one. */
.entry--split{
  display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
  column-gap:60px;row-gap:15px;align-items:start;max-width:none;
}
/* The universal selector carries no specificity, so ".entry--split > *" lost
   to ".entry h2" and every heading kept a 49 pixel top margin that its own
   paragraph did not, putting the two halves of each pair out of step. Naming
   the elements is what makes these rules win. */
.entry--split > h2{
  grid-column:1;max-width:19ch;line-height:1.14;margin-top:0;
  font-size:clamp(1.25rem,2.3vw,1.7rem);
}
.entry--split > *:not(h2){grid-column:2;max-width:62ch;margin-top:0}
/* The gap between pairs is the row gap, not a margin on the heading. A margin
   moves the heading but not the paragraph sharing its row, which left the two
   halves of every pair a line and a half out of step with each other. */
.entry--split{row-gap:36px}
@media (max-width:880px){
  .entry--split{grid-template-columns:1fr;row-gap:12px}
  .entry--split > h2{margin-top:26px}
  .entry--split > h2,.entry--split > *:not(h2){grid-column:1;max-width:none}
}

/* Navigation panels, grouped the way a large portfolio needs */
.drop-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:4px}
.drop-col-title{
  display:block;font-family:var(--f-m);font-size:.6rem;letter-spacing:.11em;
  text-transform:uppercase;color:var(--fg-3);padding:10px 12px 4px;
}
html[dir="rtl"] .drop-col-title{letter-spacing:.02em}
.has-drop{position:relative}
nav.main ul{list-style:none;margin:0;padding:0}

/* Partner logo wall */
.logowall{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:1px;background:var(--line);border:1px solid var(--line);
}
.logowall-item{
  background:var(--bg-2);min-height:96px;display:grid;place-items:center;padding:20px;
}
.logowall-item img{max-height:34px;width:auto;opacity:.82}
.logowall-item:hover img{opacity:1}
.logowall-item span{
  font-family:var(--f-d);font-weight:600;font-size:.92rem;color:var(--fg-2);text-align:center;
}
.logowall-item .on-dark{display:none}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .logowall-item .on-light{display:none}
  :root:not([data-theme="light"]) .logowall-item .on-dark{display:block}
}
:root[data-theme="dark"] .logowall-item .on-light{display:none}
:root[data-theme="dark"] .logowall-item .on-dark{display:block}

/* Footer additions */
.fgrid ul{list-style:none;margin:0;padding:0}
.signup{display:flex;gap:8px;margin-top:18px;flex-wrap:wrap}
.signup input{
  flex:1;min-width:170px;border:1px solid var(--edge);background:var(--bg-2);
  color:var(--fg);padding:10px 13px;font:400 .88rem/1 var(--f-b);
}
.signup input:focus{border-color:var(--accent);outline:none}
.signup-note{font-size:.78rem;color:var(--fg-3);margin-top:10px;max-width:38ch}
.foffices{border-top:1px solid var(--line);margin-top:40px;padding-top:26px}
.foffices .foot-h{
  font-family:var(--f-m);font-size:.64rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--fg-3);margin-bottom:14px;font-weight:500;
}
html[dir="rtl"] .foffices .foot-h{letter-spacing:.03em}
.foffice-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:16px}
.foffice-list b{display:block;font-size:.88rem}
.foffice-list span{font-size:.8rem;color:var(--fg-3)}
.linkish{
  background:none;border:0;padding:0;color:var(--fg-3);cursor:pointer;
  font:inherit;text-decoration:underline;
}
.linkish:hover{color:var(--fg)}
.fbot a{color:var(--fg-3)}
.fbot a:hover{color:var(--accent)}

/* Enquiry form */
/* The honeypot. Moved nine thousand pixels to the physical left, which in a
   right to left page is the direction the document scrolls, and which is a
   physical property in a codebase that uses logical ones everywhere else. It is
   clipped instead, the same way a screen reader only label is, so it occupies
   no space in either direction. */
.sst-hp{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.form-result{
  border:1px solid var(--line);background:var(--bg-2);padding:26px;
  border-inline-start:3px solid var(--accent);
}
.form-result--ok{border-inline-start-color:var(--good)}
.form-result--bad{border-inline-start-color:#d63638}
.form-result h3{font-size:1.2rem;margin-bottom:8px}
.form-result p{color:var(--fg-2)}

/* Language switcher, which is a segmented control of links rather than buttons */
.seg a{
  font-family:var(--f-m);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  padding:5px 10px;color:var(--fg-3);text-decoration:none;display:inline-flex;align-items:center;
  border-inline-end:1px solid var(--line-2);
}
.seg a:last-child{border-inline-end:0}
.seg a.is-current{background:var(--accent);color:var(--accent-fg)}
html[dir="rtl"] .seg a{letter-spacing:.02em}

/* Pagination */
.pagination{display:flex;gap:8px;margin-top:34px;flex-wrap:wrap}
.pagination .page-numbers{
  border:1px solid var(--edge);padding:9px 14px;color:var(--fg-2);
  font-family:var(--f-m);font-size:.75rem;
}
.pagination .page-numbers.current{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
