/* Brand faces, self-hosted (SIL Open Font Licence, licences in /assets/fonts/).
   No third-party request: the files come from this origin, like everything
   else. Archivo carries the Latin text with its width axis (75-125%), Roboto
   Flex the Cyrillic under the same family name so Russian pages keep the
   same widths, IBM Plex Sans Arabic the Arabic. unicode-range lets the
   browser fetch only the file a page actually needs (2026-09-24). */
@font-face{font-family:Archivo;src:url(/assets/fonts/archivo-latin.v1.woff2) format("woff2");font-weight:300 800;font-stretch:75% 125%;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A0-017F,U+0218-021B,U+02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2116,U+2122,U+2190-2197,U+2212,U+2248,U+2264-2265,U+25CF,U+2713}
@font-face{font-family:Archivo;src:url(/assets/fonts/robotoflex-cyrillic.v1.woff2) format("woff2");font-weight:300 800;font-stretch:75% 125%;font-style:normal;font-display:swap;unicode-range:U+0400-045F,U+0490-0493,U+049A-049B,U+04AE-04B3,U+04BA-04BB,U+04D8-04D9,U+04E8-04E9}
@font-face{font-family:"IBM Plex Sans Arabic";src:url(/assets/fonts/ibmplexsansarabic-400.v1.woff2) format("woff2");font-weight:300 500;font-style:normal;font-display:swap;unicode-range:U+0600-06FF,U+0750-077F,U+FB50-FDFF,U+FE70-FEFF,U+200C-200F}
@font-face{font-family:"IBM Plex Sans Arabic";src:url(/assets/fonts/ibmplexsansarabic-600.v1.woff2) format("woff2");font-weight:600 800;font-style:normal;font-display:swap;unicode-range:U+0600-06FF,U+0750-077F,U+FB50-FDFF,U+FE70-FEFF,U+200C-200F}
/* ============================================================
   ARTIFEX — the motion and material engine
   One file. Every page in the prototype uses it and nothing else.

   Why no library. The reference sites (reactbits, getlayers, supahero) all
   build this on Three.js and React. This site's stated position — on its own
   privacy page — is that it makes no third-party requests at all, and its
   first screen already costs about 1 MB on a phone. Three.js is another
   150 KB before a single model loads, and there is no glTF of these buildings
   to load into it, so "3D" would mean decorative geometry: for an architect,
   the one thing worse than no 3D.

   So depth here is real CSS 3D — a perspective stage with layers on separate
   Z planes, moving at their own rates — and the particles are a canvas the
   size of the viewport. Together they are about 8 KB.
   ============================================================ */

:root{
  /* the brand, unchanged */
  --ink:#0A0A0B; --ink-2:#101012; --ink-3:#16161A;
  --line-d:#232327; --line-d2:#2C2C32;
  --paper:#F7F5F1; --text:#EDEBE7;
  --muted:#9B978F; --muted-d:#837F79;
  --gold:#C5A268; --gold-2:#8C6A2F; --gold-3:#E0C89B;

  /* One family, three widths. Archivo carries a width axis from condensed to
     expanded and a weight axis from thin to black, so the display face, the
     reading face and the label face are the same letters at different cuts
     rather than three typefaces arguing with each other. Headlines are set in
     capitals at the expanded width, which is how a drawing sheet is titled. */
  --fs:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --fd:Archivo,-apple-system,"Segoe UI",sans-serif;
  --fm:Archivo,"Segoe UI",sans-serif;
  --w-wide:125;      /* display  — expanded */
  --w-text:100;      /* reading  — normal   */
  --w-narrow:78;     /* labels   — condensed */

  /* grows with the viewport: 1320px flat left a third of a 2560 display
     empty on each side. Prose keeps its own ch-limits; the frame takes
     the room. Pages that load only this file get the width too. */
  --wrap:min(1680px, 94vw);
  --pad:clamp(20px,4.4vw,64px);

  /* glass, as three settings of one material rather than three materials */
  --glass-blur:22px;
  --glass-tint:rgba(255,255,255,.045);
  --glass-edge:rgba(255,255,255,.14);
  --glass-sheen:rgba(255,255,255,.26);

  color-scheme:dark;
}
/* Arabic pages: a face with Arabic glyphs; the Latin marks stay Latin. */
html[dir="rtl"]{--fs:"IBM Plex Sans Arabic",Archivo,Tahoma,sans-serif;--fd:"IBM Plex Sans Arabic",Archivo,Tahoma,sans-serif;--fm:"IBM Plex Sans Arabic",Archivo,Tahoma,sans-serif}
html[dir="rtl"] .brand strong,html[dir="rtl"] .nav-cta,html[dir="rtl"] .fee,html[dir="rtl"] .num,html[dir="rtl"] [lang="en"]{font-family:Archivo,Arial,sans-serif}

/* The generated mobile menu exists at every width; only its styles were
   inside the narrow-screen query. Above 860px it therefore had no styles at
   all and rendered as a plain block — five nav links run together in one
   unspaced line across the top of every page, with a second "write to us"
   button beside them. Hidden by default, and the query below turns it on. */
.mob-menu[data-built]{display:none}

/* The `hidden` attribute has to actually hide.
   The browser's own rule is `[hidden]{display:none}`, which any author rule
   setting `display` on the same element beats — and that is not a hypothetical:
   `.fields{display:grid}` on the investor form and `.g-bar{display:flex}` on
   the gallery controls each silently cancelled it. The investor form stayed on
   screen behind its own "thank you", and the gallery shipped a row of dead
   buttons to anyone whose script did not run. One rule, once, for every page. */
[hidden]{display:none!important}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
/* overflow-x: CLIP, not hidden — and the difference is the whole news site.
   `hidden` on either axis makes the element a SCROLL CONTAINER, so `body`
   quietly became the page's scroller and `overflow-y` resolved to `auto`
   beside it. Chrome's loading="lazy" measures against the document viewport,
   not against a scroller some element declared halfway down a stylesheet, so
   no news photograph ever entered "view": forty-one images on /news, two
   loaded, and scrolling six hundred points changed nothing because the
   window was not what was scrolling. Measured 2026-08-27 — the files, the
   paths and the headers were all correct the whole time, and `new Image()`
   on the very same URL returned 1600x840 instantly.

   `clip` stops the horizontal overflow it was written to stop and creates no
   scroll container, so the document scrolls and lazy loading sees the page a
   reader sees. */
body{background:var(--ink);color:var(--text);font:400 16px/1.65 var(--fs);
  overflow-x:clip;-webkit-font-smoothing:antialiased}
/* height:auto matters: with only max-width, an <img width height> keeps its
   ATTRIBUTE height while the width shrinks to the container — every news
   photograph stood vertically stretched. Containers that mean to crop set
   their own height:100% below and win on specificity. */
img,video,canvas{max-width:100%;display:block;height:auto}

/* An image inside a box with a fixed ratio must FILL that box and crop, not
   run out of the bottom of it.
   These rules used to arrive with `.reeded > img`, because every one of these
   containers was fluted. When the fluting was taken off the photographs, the
   sizing left with it — and the project renders drew at their full intrinsic
   height, a 1120x700 file standing a thousand pixels tall inside a 16:11 frame
   and spilling over everything under it. The sizing belongs to the container,
   not to the material that happened to be on it. */
.shot > img,.shot > video,
.shot-tall > img,.shot-main > img,.shot-inset > img,
.shotpane > img,.pane-shot > img,
.faces > img,.face > img,.portrait > img,
.plate > img,.g-pane > img,.g-pane > video,
.noshot > img,.hero-shot > img{
  width:100%;height:100%;object-fit:cover}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
::selection{background:var(--gold);color:#141414}

.wrap{max-width:var(--wrap);margin:0 auto;padding-inline:var(--pad)}

/* ============================================================
   1. THE PARTICLE FIELD
   A canvas pinned behind everything. The script draws it; this only places it
   and decides when it is allowed to exist at all.
   ============================================================ */
.field{position:fixed;inset:0;z-index:0;pointer-events:none;
  opacity:0;transition:opacity 1.2s ease}
.field.lit{opacity:1}
/* the field is decoration: a reader who asked for less motion, or a machine
   printing the page, never sees it */
@media (prefers-reduced-motion:reduce){.field{display:none}}
@media print{.field{display:none}}

/* ============================================================
   2. GLASS
   backdrop-filter over a tinted surface, plus a specular edge. The sheen is a
   separate layer so it can catch the cursor without the blur re-rendering.
   ============================================================ */
.glass{position:relative;isolation:isolate;
  background:var(--glass-tint);
  backdrop-filter:blur(var(--glass-blur)) saturate(1.35);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.35);
  border:1px solid var(--glass-edge);
  box-shadow:0 24px 60px -30px rgba(0,0,0,.9),
             inset 0 1px 0 rgba(255,255,255,.1)}
/* the highlight that makes it read as a thick pane rather than a blurred box:
   a soft radial that follows the cursor, positioned by --mx/--my in the script */
/* Three stops, not two. A single stop fading straight to transparent spreads
   the light so thinly that the pane looks faintly lit rather than touched: the
   effect was there and nobody could see where the cursor was. A bright, tight
   core over a wide soft falloff reads as a real highlight travelling under the
   glass — the cursor's position is unmistakable, which is the whole point. */
.glass::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(420px circle at var(--mx,50%) var(--my,0%),
    var(--glass-sheen) 0%,
    rgba(255,255,255,.11) 26%,
    rgba(255,255,255,.035) 52%,
    transparent 74%);
  opacity:0;transition:opacity .4s ease}
.glass:hover::after,.glass:focus-within::after{opacity:1}
/* On a pane the reader is meant to move across — a newsletter box, a form —
   the light is brighter still and follows without the softening delay. */
.glass-lit{--glass-sheen:rgba(255,255,255,.5)}
.glass-lit::after{transition:opacity .18s ease}

.glass-quiet{--glass-blur:12px;--glass-tint:rgba(255,255,255,.03);
  --glass-edge:rgba(255,255,255,.09)}
.glass-strong{--glass-blur:34px;--glass-tint:rgba(255,255,255,.07);
  --glass-edge:rgba(255,255,255,.2)}

/* backdrop-filter is not universal. Without this, the panels become invisible
   boxes rather than degrading to solid ones. */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .glass{background:rgba(16,16,20,.86)}
}

/* ============================================================
   3. REEDED GLASS
   Fluted glass: vertical flutes that refract what is behind them. Two layers —
   the image, blurred and sliced by a repeating gradient, over the sharp image —
   so the flutes read as thickness rather than as stripes drawn on top.
   ============================================================ */
.reeded{position:relative;overflow:hidden;isolation:isolate}
.reeded > img,.reeded > video{width:100%;height:100%;object-fit:cover}
.reeded::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  backdrop-filter:blur(7px) saturate(1.2);
  -webkit-backdrop-filter:blur(7px) saturate(1.2);
  /* every second flute is transparent, so the sharp image shows through and
     the blurred one fills the rest — that alternation is the whole effect */
  -webkit-mask-image:repeating-linear-gradient(90deg,
    #000 0 calc(var(--reed,13px) * .52), transparent calc(var(--reed,13px) * .52) var(--reed,13px));
  mask-image:repeating-linear-gradient(90deg,
    #000 0 calc(var(--reed,13px) * .52), transparent calc(var(--reed,13px) * .52) var(--reed,13px))}
/* the specular line down each flute, and the shadow in each valley */
.reeded::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:repeating-linear-gradient(90deg,
    rgba(255,255,255,.11) 0 1px,
    rgba(255,255,255,.03) 1px calc(var(--reed,13px) * .3),
    rgba(0,0,0,.14) calc(var(--reed,13px) * .52) calc(var(--reed,13px) * .62),
    transparent calc(var(--reed,13px) * .62) var(--reed,13px));
  mix-blend-mode:overlay}
.reeded-fine{--reed:8px}
.reeded-wide{--reed:22px}

/* Point = see. Wherever a fluted image sits inside something hoverable, the
   pointer lifts the fluting off THAT image while its neighbours keep theirs.
   The card rails only veiled the neighbours; the flutes stayed on the card
   under the pointer, so the one being looked at was the blurred one — the
   exact reverse of what pointing means. */
.reeded::before,.reeded::after{transition:opacity .38s ease}
a:hover .reeded::before,a:hover .reeded::after,
button:hover .reeded::before,button:hover .reeded::after,
.reeded:hover::before,.reeded:hover::after{opacity:0}
@media(min-width:2200px){:root{--wrap:min(1920px, 90vw)}}

/* ============================================================
   STRIPS AND THEIR ARROWS
   Every .more strip is a paged carousel under its main frame: thumbnails in
   one row, arrows injected by engine.js railnav(), looping past the ends.
   Small videos ride the same strip (.vshot) and play into the main frame,
   muted — the practice never publishes sound.
   ============================================================ */
.more{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px;
  scroll-behavior:smooth;scrollbar-width:thin;
  scrollbar-color:rgba(255,255,255,.18) transparent}
.more > .shot,.more > .vshot{flex:0 0 auto;width:150px;margin:0}
.more > .shot > img{width:100%;height:96px;object-fit:cover}
.vshot{position:relative;cursor:pointer;border:1px solid rgba(255,255,255,.14)}
/* a keyboard reader has to see which tile Enter will play */
.vshot:focus-visible,.more .shot:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.vshot video,.vshot img{width:100%;height:96px;object-fit:cover;display:block;
  pointer-events:none}
/* the hover teaser sits over the poster; the play mark stays on top (#26) */
.vshot video.teaser{position:absolute;inset:0;width:100%;height:100%;z-index:0}
.vshot video.teaser[hidden]{display:none}
.vshot::after{content:"▶";position:absolute;inset:0;display:grid;
  place-items:center;color:#fff;font-size:20px;
  background:rgba(8,8,10,.35);transition:background .2s}
.vshot:hover::after{background:rgba(8,8,10,.12)}
.railnav{display:flex;gap:8px;margin-top:10px}
.rn{width:38px;height:38px;display:grid;place-items:center;
  border:1px solid rgba(255,255,255,.22);color:#fff;font-size:16px;
  background:rgba(10,10,11,.5);transition:background .2s,border-color .2s}
.rn:hover{background:var(--gold);border-color:var(--gold);color:#141414}
/* a video playing in the main frame fills it edge to edge */
.shot > video{width:100%;height:100%;object-fit:cover;display:block}

/* --- when NOT to flute the whole image ---------------------------------
   Fluted glass at 13px or wider makes a building unrecognisable. Tested side
   by side against the plain image: at 22px the administrative building reads
   as an abstract pattern. For a practice whose photography is the strongest
   thing it owns — and the first reason a client makes contact — veiling every
   render in glass works against the page.

   So the material is used two ways instead, and full flutes are kept for
   atmosphere shots where the subject is a room rather than a building. */

/* 1. A FRAME: flutes hold the edges, the centre stays sharp. The building is
      seen; the glass is felt. This is the default for project images. */
.reeded-frame::before,.reeded-frame::after{
  -webkit-mask-image:
    repeating-linear-gradient(90deg,#000 0 calc(var(--reed,13px) * .52),
      transparent calc(var(--reed,13px) * .52) var(--reed,13px)),
    linear-gradient(90deg,#000 0%,transparent 26%,transparent 74%,#000 100%);
  mask-image:
    repeating-linear-gradient(90deg,#000 0 calc(var(--reed,13px) * .52),
      transparent calc(var(--reed,13px) * .52) var(--reed,13px)),
    linear-gradient(90deg,#000 0%,transparent 26%,transparent 74%,#000 100%);
  -webkit-mask-composite:source-in;
  mask-composite:intersect}
.reeded-frame::after{
  -webkit-mask-image:linear-gradient(90deg,#000 0%,transparent 26%,transparent 74%,#000 100%);
  mask-image:linear-gradient(90deg,#000 0%,transparent 26%,transparent 74%,#000 100%)}

/* 2. A REVEAL: the flutes retract when the pointer arrives, the way a hand
      clears a misted pane. The image is glass until someone looks at it. */
.reeded-reveal::before,.reeded-reveal::after{
  transition:opacity .55s var(--ease)}
.reeded-reveal:hover::before,.reeded-reveal:focus-within::before{opacity:0}
.reeded-reveal:hover::after,.reeded-reveal:focus-within::after{opacity:.25}
@media (prefers-reduced-motion:reduce){
  .reeded-reveal::before,.reeded-reveal::after{transition:none}
}
/* on a touch screen there is no hover, so the reveal would trap the image
   behind glass permanently */
@media (hover:none){
  .reeded-reveal::before{opacity:0}
  .reeded-reveal::after{opacity:.3}
}

/* ============================================================
   4. DEPTH
   A perspective stage. Children sit on their own Z plane and the script moves
   them at different rates as the page scrolls, which is what makes the descent
   read as going INTO the page rather than down it.
   ============================================================ */
.stage{perspective:1400px;perspective-origin:50% 40%;transform-style:preserve-3d;
  position:relative}
.layer{will-change:transform;transform-style:preserve-3d}
.layer[data-z]{transition:transform .08s linear}

/* a card that turns toward the cursor. The angles come from --tx/--ty, which
   the script sets per element; the transition makes the return home soft
   without making the follow feel laggy. */
.tilt{transform:perspective(900px)
  rotateX(var(--ty,0deg)) rotateY(var(--tx,0deg)) translateZ(0);
  transition:transform .5s var(--ease)}
.tilt.tracking{transition:transform .08s linear}

/* ============================================================
   5. ARRIVAL
   Everything enters once, upward, in sequence. Nothing loops: motion that
   repeats forever stops being information and becomes wallpaper.
   ============================================================ */
/* The hiding is scoped to html.motion, which the script adds as its very first
   statement. Without that class every block is simply visible.

   This is not defensive style for its own sake. The first version hid
   everything by default and revealed it from an IntersectionObserver, so any
   failure between the two — a script that does not load, an observer that
   delivers nothing, a browser extension that breaks it — left a page with
   nothing on it at all. That was observed: a page whose markup was complete
   rendered as a photograph and no words. Content must never wait on
   JavaScript to exist. */
html.motion [data-rise]{opacity:0;transform:translate3d(0,26px,0);
  transition:opacity .8s var(--ease),
             transform .9s var(--ease)}
html.motion [data-rise].in{opacity:1;transform:none}
[data-rise="2"]{transition-delay:.08s}
[data-rise="3"]{transition-delay:.16s}
[data-rise="4"]{transition-delay:.24s}
[data-rise="5"]{transition-delay:.32s}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  [data-rise]{opacity:1;transform:none;transition:none}
  .tilt{transform:none!important}
  .layer{transform:none!important}
}

/* ============================================================
   6. TYPE
   ============================================================ */
/* Labels take the condensed cut. Narrow letters at wide tracking read as a
   drawing annotation rather than as body text that happens to be small. */
.eyebrow{font:600 condensed 11px/1.6 var(--fm);letter-spacing:.24em;font-stretch:78%;
  text-transform:uppercase;color:var(--gold)}
/* The width runs opposite to the size, which is how a type family is meant to
   be used. A headline set large is already loud, so it takes the narrower cut
   and stays on three lines instead of six; a small heading has room to spread,
   so it takes the expanded one and reads as a title rather than as bold text.
   Same letters, three cuts — the hierarchy is the width, not just the size. */
h1,h2,h3{font-family:var(--fd);font-weight:700;font-stretch:112%;
  text-transform:uppercase;letter-spacing:-.012em;
  line-height:.98;color:#fff}
h1{font-weight:800;font-stretch:100%}
h2{font-stretch:118%}
h3{font-stretch:125%;font-weight:600;letter-spacing:.008em}
/* The emphasised word keeps the headline's own cut. The first version dropped
   it to lowercase at weight 400 — the theory was that mixed case would soften
   a shouted line — but inside an all-caps 800-weight sentence a thin lowercase
   word reads as a typo, not an emphasis: two typefaces fighting in one line,
   and "built" was the word that lost. Gold alone carries the emphasis now. */
h1 em,h2 em{font-style:normal;font-weight:inherit;font-stretch:inherit;
  text-transform:inherit;letter-spacing:inherit;color:var(--gold)}
/* Capitals need roughly a third less size than lowercase for the same presence
   — they have no descenders and no x-height to read past. At the old 86px a
   six-word headline ran to six lines and pushed the portrait off the screen. */
h1{font-size:clamp(29px,4.3vw,58px)}
h2{font-size:clamp(28px,4.4vw,58px);line-height:1.08}
h3{font-size:clamp(19px,2.2vw,27px);line-height:1.2}
.lede{font-size:clamp(15.5px,1.5vw,19px);line-height:1.72;color:#C9C5BE;
  max-width:56ch}
p{color:var(--muted);max-width:68ch}
.num{font-family:var(--fd);font-stretch:125%;font-size:clamp(30px,4.4vw,56px);color:var(--gold);
  line-height:1;font-variant-numeric:tabular-nums}

/* ============================================================
   7. THE SHELL — one header and one footer on every page
   ============================================================ */
.nav{position:fixed;top:0;left:0;right:0;z-index:60;
  padding-block:14px;transition:background .3s,border-color .3s;
  border-bottom:1px solid transparent}
.nav.stuck{background:rgba(10,10,11,.72);border-bottom-color:var(--line-d);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
.nav-in{max-width:var(--wrap);margin:0 auto;padding-inline:var(--pad);
  display:flex;align-items:center;gap:26px}
.brand{display:flex;align-items:center;gap:11px;flex:0 0 auto;
  font-family:var(--fd);font-stretch:125%;font-size:17px;letter-spacing:.05em;color:#fff}
.brand img{width:27px;height:27px}
/* Labels at or under 11px sit in --muted (6.8:1 on the ink), never in
   --muted-d (4.97:1): at that size the darker grey is at the AA line on a
   desktop and under it on a phone. */
.brand small{display:block;font:500 condensed 10px/1 var(--fm);letter-spacing:.24em;
  text-transform:uppercase;color:var(--muted);margin-top:5px}
.nav-links{display:flex;gap:22px;margin-left:auto;
  font:500 11.5px/1 var(--fs);letter-spacing:.15em;text-transform:uppercase}
.nav-links a{color:rgba(255,255,255,.7);padding-bottom:4px;
  border-bottom:1px solid transparent;transition:color .2s,border-color .2s}
.nav-links a:hover,.nav-links a[aria-current]{color:#fff;border-color:var(--gold)}
/* WhatsApp is the first thing a Gulf reader reaches for, and it was the one
   door the header did not have: gold, so it reads as the way to talk rather
   than one more page. The generated mobile menu clones it with the rest. */
.nav-links .nav-wa{color:var(--gold);border-color:rgba(197,162,104,.45)}
.nav-links .nav-wa:hover{color:var(--gold-3);border-color:var(--gold)}
.nav-cta{flex:0 0 auto;font:600 11.5px/1 var(--fs);letter-spacing:.15em;
  text-transform:uppercase;border:1px solid rgba(255,255,255,.3);
  padding:12px 18px;color:#fff;transition:all .2s}
.nav-cta:hover{background:var(--gold);border-color:var(--gold);color:#141414}
.burger{display:none;flex-direction:column;gap:5px;margin-left:auto;padding:7px}
.burger span{width:22px;height:1.5px;background:#fff;transition:transform .22s}

.foot{position:relative;z-index:2;border-top:1px solid var(--line-d);
  background:var(--ink-2);padding-block:clamp(40px,6vw,72px) 30px;margin-top:0}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr;
  gap:clamp(26px,4vw,60px)}
.foot h3{font-size:20px;margin-bottom:14px}
.foot a{color:var(--muted);font-size:14px;line-height:2.1;display:block;
  transition:color .2s}
.foot a:hover{color:var(--gold)}
.foot-base{margin-top:38px;padding-top:20px;border-top:1px solid var(--line-d);
  display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;
  font:500 condensed 11px/1 var(--fm);letter-spacing:.14em;color:var(--muted)}

/* ============================================================
   8. PIECES USED ON EVERY PAGE
   ============================================================ */
.btn{display:inline-flex;align-items:center;gap:11px;
  font:600 11px/1 var(--fs);letter-spacing:.17em;text-transform:uppercase;
  padding:17px 26px;background:var(--gold);color:#141414;
  transition:transform .3s var(--ease),box-shadow .3s}
.btn:hover{transform:translateY(-2px);
  box-shadow:0 16px 34px -14px rgba(197,162,104,.6)}
.btn.ghost{background:transparent;color:#fff;
  border:1px solid rgba(255,255,255,.32)}
.btn.ghost:hover{background:rgba(255,255,255,.07);box-shadow:none}

.sec{position:relative;z-index:2;padding-block:clamp(70px,10vw,150px)}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;
  gap:24px;margin-bottom:clamp(28px,4vw,56px);flex-wrap:wrap}
.sec-head h2{max-width:20ch}

/* the panel that carries most content: glass over the moving background */
.pane{padding:clamp(22px,3vw,38px)}

/* a link that says where it goes rather than just being blue */
.go{display:inline-flex;align-items:center;gap:10px;
  font:500 condensed 11.5px/1 var(--fm);letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);transition:gap .25s}
.go:hover{gap:16px}

/* The phone sizes for the wordmark and the footer stay at 860px. */
@media(max-width:860px){
  .brand{gap:8px;font-size:13px}
  .brand img{width:24px;height:24px;flex:0 0 24px}
  .brand small{font-size:10px;letter-spacing:.18em}
  .foot-grid{grid-template-columns:1fr;gap:26px}
  :root{--glass-blur:14px}
}

/* The header folds at 1120px: eight links, the wordmark and the language
   control stop fitting on one row below that (measured 2026-09-24: at 916px
   the links ran to 995px on the live home page, off the edge, with no
   burger to reach them). */
@media(max-width:1120px){
  .nav-links,.nav-cta{display:none}
  .nav-in{gap:10px}
  .brand{min-width:0}
  .brand span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .burger{display:flex;flex:0 0 auto}

  /* Four pages shipped a burger with nothing behind it, so below 860px — where
     the links are hidden — they had no navigation at all. The script now builds
     this panel out of the page's own .nav-links wherever one is missing, and
     marks it data-built. The styles live here so no page has to carry them, and
     a page that already defines its own .mob-menu is untouched. */
  .mob-menu[data-built]{display:flex;position:fixed;inset:64px 0 auto;z-index:60;
    flex-direction:column;
    padding:8px var(--pad) 20px;
    background:rgba(10,10,11,.95);
    backdrop-filter:blur(20px) saturate(1.3);
    -webkit-backdrop-filter:blur(20px) saturate(1.3);
    border-bottom:1px solid var(--line-d);
    transform:translateY(-10px);opacity:0;visibility:hidden;
    transition:transform .26s ease,opacity .26s ease,visibility 0s .26s}
  /* visibility, not transform alone: a panel parked out of sight by a transform
     keeps its links in the tab order, and a keyboard reader falls into a menu
     they cannot see. */
  .mob-menu[data-built].open{transform:none;opacity:1;visibility:visible;
    transition:transform .26s ease,opacity .26s ease,visibility 0s}
  .mob-menu[data-built] a{padding:15px 2px;border-bottom:1px solid var(--line-d);
    font:600 12px/1 var(--fs);letter-spacing:.14em;text-transform:uppercase;
    color:rgba(255,255,255,.84)}
  .mob-menu[data-built] a:last-child{border-bottom:0}
  .mob-menu[data-built] a[aria-current]{color:var(--gold)}
}

/* ============================================================
   THE LANGUAGE SWITCHER
   The markup is written into every page by ops/build_i18n.py, and the
   styles for it were only ever in site.css. These pages do not load
   site.css, so on the live site the switcher appeared as the browser's
   own disclosure triangle with EN stacked under it, outside the nav.
   Copied rather than rewritten: two switchers styled twice would drift.
   ============================================================ */
.flag-sprite{position:absolute;width:0;height:0;overflow:hidden}
.langs-nav{position:relative;flex:0 0 auto}
.langs-nav summary{display:flex;align-items:center;gap:6px;cursor:pointer;
  list-style:none;padding:7px 8px;color:rgba(255,255,255,.72);
  border:1px solid transparent;transition:color .16s,border-color .16s}
.langs-nav summary::-webkit-details-marker{display:none}
.langs-nav summary:hover{color:#fff;border-color:var(--line-d2)}
.langs-nav summary:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.langs-nav[open] summary{color:var(--gold);border-color:var(--line-d2)}
.lang-globe{width:17px;height:17px;flex:0 0 auto}
.lang-now{font:500 11px/1 var(--fm);letter-spacing:.12em}
.lang-list{position:absolute;top:calc(100% + 8px);right:0;z-index:80;
  min-width:186px;padding:7px;background:var(--ink-2);
  border:1px solid var(--line-d2);box-shadow:0 22px 44px -20px rgba(0,0,0,.8)}
.lang-row{display:flex;align-items:center;gap:11px;padding:9px 10px;
  font:400 13.5px/1.3 var(--fs);color:rgba(255,255,255,.78);font-weight:400}
.lang-row:hover{background:var(--ink-3);color:#fff}
.lang-row:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
.lang-row[aria-current]{color:var(--gold);background:rgba(197,162,104,.09)}
.flag{width:23px;height:15.3px;flex:0 0 auto;
  box-shadow:0 0 0 1px rgba(255,255,255,.22)}
.lang-name{flex:1 1 auto}
.lang-code{font:500 11px/1 var(--fm);letter-spacing:.12em;color:var(--muted)}
.lang-row[aria-current] .lang-code{color:var(--gold-2)}
@media(max-width:1120px){
  .langs-nav{margin-left:auto}
  .langs-nav summary{padding:7px 4px;gap:4px}
  .lang-now{display:none}
}

/* the switcher shows the flag of the page you are reading */
.flag-now{width:22px;height:14.6px;flex:0 0 auto;
  box-shadow:0 0 0 1px rgba(255,255,255,.25)}
.langs-nav summary .lang-globe{display:none}
/* Skip link — invisible until focused, then a pill at the top-left (RTL flips
   it in rtl.css). The ten engine pages had no skip link at all and no way to
   reach <main> from the keyboard past a seventy-link header. */
.skip{position:fixed;top:8px;left:8px;z-index:300;transform:translateY(-200%);
  background:var(--ink,#111);color:var(--paper,#fff);padding:.5rem .9rem;border-radius:999px;
  font:600 .85rem/1 system-ui,sans-serif;text-decoration:none;transition:transform .15s}
.skip:focus{transform:translateY(0);outline:2px solid var(--gold,#c5a268);outline-offset:2px}

/* ---- the enlarged picture (gallery.js) ----
   Shared, because every page that loads gallery.js opens this box. It
   used to live inline on four pages only (projects, investors, ceo, team);
   the 132 project pages loaded the script without it, so a click dropped
   an unstyled picture under the footer and the scroll lock froze the page
   (reported 2026-09-22 on /work/madinah-hotel). */
.lightbox{position:fixed;inset:0;z-index:200;display:flex;align-items:center;
  justify-content:center;gap:clamp(8px,2vw,26px);padding:clamp(14px,4vw,48px);
  background:rgba(6,6,8,.93);backdrop-filter:blur(14px) saturate(1.1);
  -webkit-backdrop-filter:blur(14px) saturate(1.1)}
.lightbox[hidden]{display:none}
.lb-figure{max-width:min(1500px,92vw);max-height:82vh;display:flex;
  flex-direction:column;gap:14px;margin:0}
.lb-figure img{max-width:100%;max-height:72vh;object-fit:contain;
  border:1px solid var(--line-d2);background:#000}
.lb-figure figcaption{font-size:13.5px;line-height:1.6;color:var(--muted);
  max-width:78ch}
.lb-close,.lb-prev,.lb-next{flex:0 0 auto;width:46px;height:46px;
  border:1px solid var(--line-d2);background:rgba(20,20,24,.8);color:#fff;
  font-size:20px;line-height:1;border-radius:50%;transition:background .2s}
.lb-close:hover,.lb-prev:hover,.lb-next:hover{background:rgba(40,40,48,.95)}
.lb-close{position:absolute;top:clamp(12px,3vw,28px);right:clamp(12px,3vw,28px)}
.lb-go{position:absolute;left:50%;transform:translateX(-50%);
  bottom:clamp(12px,3vw,30px);white-space:nowrap}
.lb-go[hidden]{display:none}
@media(max-width:640px){
  .lb-prev,.lb-next{position:absolute;bottom:76px;z-index:2}
  .lb-prev{left:16px} .lb-next{right:16px}
  .lb-figure{max-height:70vh}
}

/* ---------- About us: the nav item, the page, the bubble ----------
   PAIRED WITH THE OTHER STYLESHEET. This site is served by two: engine.css
   for the main pages and site.css for the service and error pages. A rule in
   one is invisible on the other — the bubble was written into site.css only
   and came out on the home page as a 1489px strip lying at the bottom of the
   document, because position:fixed was in a file that page never loads
   (measured 2026-08-29). Anything below that changes must change in both. */
.nav-about{flex:0 0 auto;white-space:nowrap;font:600 11px/1 var(--fs);
  letter-spacing:.12em;text-transform:uppercase;padding:9px 9px;
  color:rgba(255,255,255,.66);transition:color .18s}
.nav-about:hover,.nav-about[aria-current="page"]{color:var(--gold)}

.facts-list{list-style:none;margin:18px 0 0;padding:0}
.facts-list li{padding:11px 0;border-bottom:1px solid var(--line);
  font-size:15px;line-height:1.6}
.facts-list li:last-child{border-bottom:0}
.facts-list b{color:var(--gold);font-weight:600}

.offices{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:26px;margin:20px 0 26px}
.offices h3{font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gold);margin-bottom:8px}
.offices p{font-size:14.5px;line-height:1.75}
.reg{font-size:12.5px;color:var(--muted-d);line-height:1.7;margin-bottom:14px}
.social{font-size:14px;line-height:2}
.social a{color:var(--gold-3)}
.social a:hover{color:var(--gold)}
.quote{font-style:italic;color:var(--muted-d);border-left:2px solid var(--gold);
  padding-left:18px;margin-top:16px;line-height:1.8}
.download-pane{border-top:1px solid var(--line);padding-top:34px}

/* ============================================ THE ABOUT PAGE'S PICTURES ===
   The page argued about buildings without showing any. These rules are in
   BOTH stylesheets, byte for byte, because the site is served by two and a
   rule in one is simply absent on everything the other serves — the same
   fault that left the portfolio bubble lying flat on the home page.

   A caption is a name and a place, nothing else. The grid is symmetric
   (auto-fit, equal columns), so it takes three cards or five without being
   told which; the lopsided two-column layouts elsewhere on this site are a
   different thing and stay that way. */
.ab-wrap{width:100%}   /* a grid item is sized to its content unless
                          told otherwise, and the hero IS a grid */
.ab-banner{margin:38px 0 0;border-radius:14px;overflow:hidden;
  border:1px solid var(--line)}
.ab-banner img{display:block;width:100%;
  height:clamp(230px,36vw,440px);object-fit:cover}
.ab-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));
  gap:22px;margin-top:38px}
.ab-grid figure{margin:0}
.ab-grid img{display:block;width:100%;aspect-ratio:3/2;object-fit:cover;
  border-radius:12px;border:1px solid var(--line)}
.ab-grid figcaption{margin-top:10px;font-size:12.5px;line-height:1.55;
  color:var(--muted-d)}
.ab-grid figcaption b{display:block;margin-bottom:2px;color:var(--gold);
  font-weight:600;font-size:12px;letter-spacing:.13em;text-transform:uppercase}
.ab-portrait{margin:16px 0 0;max-width:290px}
.ab-portrait img{display:block;width:100%;height:auto;border-radius:12px;
  border:1px solid var(--line)}
@media (max-width:700px){
  .ab-portrait{max-width:210px}
}

/* THE BUBBLE. Fixed, small, and out of the way of the thumb: bottom-left,
   because the right is where a phone's own back gesture and most chat
   widgets live. Drawn as an actual bubble now (client, 2026-09-01): a glass
   sphere with a shine spot, floating gently. The float animates `translate`
   so the hover scale on `transform` composes instead of fighting it. */
.pf-bubble{position:fixed;left:20px;bottom:20px;z-index:60;
  width:56px;height:56px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.18),
    rgba(14,14,17,.88) 58%);
  border:1px solid rgba(197,162,104,.55);color:var(--gold);
  box-shadow:0 10px 30px rgba(0,0,0,.38),
    inset 0 0 18px rgba(197,162,104,.14);
  backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
  animation:pf-float 3.6s ease-in-out infinite;
  transition:background .18s,border-color .18s,color .18s,transform .18s}
.pf-bubble::after{content:"";position:absolute;top:9px;left:13px;
  width:15px;height:8px;border-radius:50%;
  background:rgba(255,255,255,.34);filter:blur(1px);
  transform:rotate(-24deg)}
.pf-bubble:hover{background:var(--gold);border-color:var(--gold);
  color:#141414;transform:scale(1.07)}
.pf-bubble svg{width:20px;height:20px;flex:none}
.pf-bubble-text{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}
@keyframes pf-float{0%,100%{translate:0 0}50%{translate:0 -5px}}
@media (max-width:720px){
  .pf-bubble{left:14px;bottom:14px;width:50px;height:50px}
}
@media (prefers-reduced-motion:reduce){
  .pf-bubble{animation:none;transition:none}
  .pf-bubble:hover{transform:none}
}

/* ============================================ TOP-100 POLISH (2026-09-24) ===
   Paired like everything below the marker above. The audit measured:
   form fields at 14.5px on phones (iOS zooms any field under 16px and the
   page then sits sideways); a keyboard ring on some controls and none on
   the rest; footer "direct" links 20px tall; a link inside a sentence told
   apart by colour alone; and main pages that printed as a black sheet.

   THE SCALE. One set of steps for type and one for motion, so a new
   component chooses a step instead of inventing a number. The easing that
   was written out seven times is now the token. */
:root{
  --t-2xs:11px;--t-xs:12.5px;--t-sm:14px;--t-base:15.5px;--t-md:17px;
  --t-lg:clamp(20px,2.2vw,26px);--t-xl:clamp(28px,4vw,44px);
  --t-2xl:clamp(38px,6.4vw,78px);
  --ease:cubic-bezier(.22,.8,.24,1);--ease-soft:cubic-bezier(.22,.61,.36,1);
  --d-1:.18s;--d-2:.32s;--d-3:.6s;--d-4:.9s;
  --tap:44px
}

/* the keyboard ring: every focusable thing, on dark and on paper */
:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.on-paper :focus-visible,.paper :focus-visible,.sec.on-paper :focus-visible{
  outline-color:var(--gold-2)}
:focus:not(:focus-visible){outline:none}

/* a link inside a sentence is underlined, not only coloured */
.close-note a,.lede a:not([class]),.sec p a:not([class]),.sheet p a:not([class]){
  text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px}

/* a finger needs 44px; these were 20 */
.pc-direct a{display:inline-flex;align-items:center;min-height:var(--tap)}
@media (pointer:coarse){
  .foot a,.foot-links a,.lang-row,.nav-links a,.mob-menu a{
    min-height:var(--tap);display:inline-flex;align-items:center}
}

/* phones never zoom into a field */
@media (max-width:900px){
  input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]),
  select,textarea{font-size:16px}
}

/* PRINT. A reader who prints a project, the About page or the investors'
   page gets black type on white, the pictures, the figures and the
   address, and none of the chrome. */
@media print{
  @page{margin:14mm 12mm}
  .field,.nav,.mob-menu,.burger,.langs-nav,.skip,.totop,.progress,.lb,
  .lightbox,.pf-bubble,.more,.gal-note,.films,form,.form,.nav-cta,
  .lang-hint,video{display:none!important}
  html,body{background:#fff!important;color:#111!important}
  body *{color:#111!important;background-color:transparent!important;
    box-shadow:none!important;text-shadow:none!important;
    -webkit-text-fill-color:currentColor!important}
  [data-rise],.reveal{opacity:1!important;transform:none!important}
  .sheet,main{padding-top:0!important}
  img{max-width:100%!important;height:auto;break-inside:avoid}
  h1,h2,h3{break-after:avoid}
  section,article,figure,.facts,.foot-grid{break-inside:avoid}
  a[href^="http"]:not([href*="artifexceo.com"])::after{
    content:" (" attr(href) ")";font-size:9pt}
}

/* the language hint (common.js): bottom centre, clear of the portfolio
   bubble on the left and the back-to-top button on the right */
.lang-hint{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);
  z-index:130;display:flex;align-items:center;gap:10px;
  width:max-content;max-width:min(440px,calc(100vw - 150px));
  padding:8px 8px 8px 16px;border-radius:12px;
  background:rgba(14,14,17,.95);border:1px solid rgba(197,162,104,.45);
  color:#EDEBE7;font:500 14px/1.45 var(--fs);
  box-shadow:0 14px 34px rgba(0,0,0,.42);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.lang-hint p{margin:0;flex:1 1 auto}
.lang-hint a{display:inline-flex;align-items:center;min-height:40px;
  padding:0 14px;border-radius:8px;background:var(--gold);color:#141414;
  font-weight:600;white-space:nowrap;text-decoration:none}
.lang-hint button{flex:none;width:40px;height:40px;border:0;border-radius:8px;
  background:transparent;color:inherit;font-size:22px;line-height:1;cursor:pointer}
.lang-hint button:hover{background:rgba(255,255,255,.08)}
@media (max-width:720px){
  .lang-hint{left:76px;right:12px;bottom:14px;transform:none;width:auto;
    max-width:none;font-size:13.5px}
}

/* projects in this field, on each service page (ops/build_project_pages.py) */
.related-work .k{font:600 11px/1.5 var(--fm);letter-spacing:.18em;
  text-transform:uppercase;color:var(--gold);margin-bottom:18px}
.rw-list{list-style:none;margin:0;padding:0;display:grid;gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
.rw-list a{display:block;border:1px solid var(--line-d,rgba(255,255,255,.1));
  border-radius:10px;overflow:hidden;color:inherit;text-decoration:none;
  transition:border-color var(--d-1) var(--ease),transform var(--d-2) var(--ease)}
.rw-list a:hover{border-color:var(--gold);transform:translateY(-2px)}
.rw-list img{display:block;width:100%;aspect-ratio:16/10;height:auto;object-fit:cover}
.rw-list span{display:block;padding:11px 13px;font:600 14px/1.35 var(--fd)}

/* Between the fold (1120px) and a wide desktop the eight header links set a
   little narrower: at 1130px the Russian row ran to 1213px, the Uzbek to
   1196px (measured 2026-09-24). Archivo carries a width axis, so this is
   the same face, not a substitute. */
@media (max-width:1440px){
  .nav-links{gap:15px;letter-spacing:.1em;font-stretch:87.5%}
}

/* two "go" links stacked in a section head */
.sec-links{display:flex;flex-direction:column;gap:12px;align-items:flex-start}

/* the process page: six stages, each with what the client holds after it */
.proc-intro{max-width:66ch;font-size:var(--t-md);line-height:1.7;color:var(--muted);
  margin-bottom:clamp(30px,4vw,54px)}
.proc-steps{list-style:none;margin:0;padding:0;counter-reset:none;
  border-top:1px solid var(--line-d,rgba(255,255,255,.1))}
.proc-step{display:grid;grid-template-columns:clamp(64px,9vw,120px) 1fr;
  gap:clamp(16px,3vw,40px);padding:clamp(26px,3.4vw,44px) 0;
  border-bottom:1px solid var(--line-d,rgba(255,255,255,.1))}
.proc-no{font:600 var(--t-xl)/1 var(--fd);font-stretch:125%;color:var(--gold);
  font-variant-numeric:tabular-nums}
.proc-body h2{font-size:var(--t-lg);margin:0 0 10px}
.proc-body p{max-width:62ch;line-height:1.7;margin:0 0 18px}
.proc-body .k{font:600 11px/1.5 var(--fm);letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);margin-bottom:8px}
.proc-body ul{margin:0 0 18px;padding-left:18px;line-height:1.8}
@media (max-width:600px){.proc-step{grid-template-columns:1fr;gap:8px}}

/* ONE ICON SET (top-100 #66). WhatsApp, Telegram and every download link
   carry the same 1.7px line glyph, drawn in the link's own colour through a
   mask, so no markup changes and the icon follows hover and theme. A link
   that already holds its own svg keeps it. The glyphs are data: URIs, which
   the CSP's img-src already allows. */
:root{
  --ico-wa:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.5 12a8.5 8.5 0 0 1-12.6 7.45L3.5 20.5l1.1-4.2A8.5 8.5 0 1 1 20.5 12z'/%3E%3Cpath d='M9.2 8.4c.3-.5.8-.5 1.1 0l.8 1.6c.1.3 0 .6-.2.8l-.5.5c.5 1.1 1.4 2 2.5 2.5l.5-.5c.2-.2.5-.3.8-.2l1.6.8c.5.3.5.8 0 1.1-.8.5-1.8.6-2.7.2a8 8 0 0 1-4-4c-.4-.9-.3-1.9.1-2.8z'/%3E%3C/svg%3E");
  --ico-tg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 4.5 3 11.3l6 2.2 2.3 6 3.3-4 4.4 3.3z'/%3E%3Cpath d='m9 13.5 8.2-6.1'/%3E%3C/svg%3E");
  --ico-dl:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.5v11.5'/%3E%3Cpath d='m7 10.5 5 5 5-5'/%3E%3Cpath d='M4 20.5h16'/%3E%3C/svg%3E")
}
a[href^="https://wa.me/"]:not(:has(svg,img))::before,
a[href^="https://t.me/"]:not(:has(svg,img))::before,
a[download]:not(.pf-bubble):not(:has(svg,img))::before{
  content:"";display:inline-block;flex:none;width:1.1em;height:1.1em;
  margin-inline-end:.45em;vertical-align:-.18em;background:currentColor;
  -webkit-mask:var(--ico) center/contain no-repeat;mask:var(--ico) center/contain no-repeat}
a[href^="https://wa.me/"]{--ico:var(--ico-wa)}
a[href^="https://t.me/"]{--ico:var(--ico-tg)}
a[download]{--ico:var(--ico-dl)}

/* the consent box on every public form (common.js holds the send until it
   is ticked, and names the box when it is not) */
.consent{display:flex;align-items:flex-start;gap:11px;min-height:var(--tap);
  margin:4px 0 12px;grid-column:1/-1;flex-basis:100%;width:100%;
  font:400 13.5px/1.55 var(--fs);cursor:pointer;text-align:start}
.consent input{flex:none;width:20px;height:20px;margin:1px 0 0;
  accent-color:var(--gold);cursor:pointer}
.consent span{opacity:.86}
.consent-missing span{opacity:1;color:#f3b4a2}
.consent-note{grid-column:1/-1;flex-basis:100%;margin:-4px 0 12px;
  font:500 13px/1.5 var(--fs);color:#f3b4a2}

/* the next-edition offer after a download (common.js), on the language
   hint's card */
.next-edition{flex-wrap:wrap;max-width:min(460px,calc(100vw - 32px));padding:14px 14px 12px 16px}
.next-edition .ne-q{flex:1 1 100%;margin:0 0 8px;font-weight:600}
.next-edition input[type=email]{flex:1 1 100%;min-height:40px;padding:8px 10px;border-radius:8px;
  border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.06);color:inherit;font:inherit}
.next-edition .consent{margin:8px 0 4px;font-size:12.5px}
.next-edition .ne-acts{display:flex;gap:8px;width:100%;justify-content:space-between}
.next-edition .ne-send{min-height:40px;padding:0 16px;border:0;border-radius:8px;
  background:var(--gold);color:#141414;font-weight:600;cursor:pointer}
.next-edition .ne-close{width:40px;height:40px;border:0;border-radius:8px;background:transparent;
  color:inherit;font-size:22px;cursor:pointer}
.next-edition .hp{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* the brief in three steps (brief-steps.js, top-100 #81) */
form[data-steps] .f-row[hidden],form[data-steps] .f-two[hidden],
form[data-steps] .f-send[hidden],form[data-steps] [hidden]{display:none!important}
.brief-head{grid-column:1/-1;margin:0 0 18px}
.brief-bar{display:flex;gap:6px;margin-bottom:10px}
.brief-bar i{flex:1;height:3px;border-radius:2px;background:rgba(255,255,255,.14)}
.brief-bar i.done{background:rgba(197,162,104,.55)}
.brief-bar i.on{background:var(--gold)}
.brief-step{margin:0;font:600 12px/1.4 var(--fm);letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}
.brief-nav{grid-column:1/-1;display:flex;gap:10px;justify-content:space-between;margin-top:6px}
.brief-nav .brief-next{margin-inline-start:auto}
