/* Executive AI Studio, design tokens
 *
 * Bureau (editorial authority: all-serif, hairline rules, generous margins)
 * recoloured to the 92e1-lion-mane-circuit mark. Every colour below is sampled
 * from that file, not invented:
 *   navy  #091930  the logo's ground
 *   cyan  #05F3F3  the lion's facets , DARK SURFACES ONLY, fails contrast on paper
 *   blue  #097AD6  the mane circuits
 *   brass #C0AF84  the circuit terminal nodes
 *
 * The register the name earns: a studio is a room where people make something by
 * hand and put the finishing touches on before it goes out. Warm paper, precise
 * rules, one live accent.
 */

:root {
  /* surfaces, light is the default ground; navy is the plate the logo sits on */
  --paper:      #FBFAF7;
  --paper-2:    #F3F0E9;
  --paper-3:    #E9E4D9;
  --navy-900:   #06111F;
  --navy-800:   #091930;   /* logo ground */
  --navy-700:   #0F2542;
  --navy-600:   #17355C;

  /* ink */
  --ink:        #0E1B2E;
  --ink-2:      #46566C;
  --ink-3:      #7C8798;
  --on-navy:    #EFEDE6;
  --on-navy-2:  #9FB0C6;

  /* accents */
  --brass:      #A8823F;   /* darkened from the node colour for contrast on paper */
  --brass-lite: #C0AF84;   /* the sampled node colour, use on navy */
  --blue:       #0A63B0;   /* darkened from #097AD6 for AA on paper */
  --blue-lite:  #097AD6;   /* sampled, use on navy */
  --cyan:       #05F3F3;   /* NEVER on paper. Navy only. */

  --rule:       #DED7C8;
  --rule-navy:  #1D3454;

  /* type, Bureau's all-serif spine, one grotesque for labels */
  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --body:    "Source Serif 4", Georgia, serif;
  --label:   "Inter Tight", system-ui, -apple-system, sans-serif;
  --mono:    ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* scale */
  --step--1: clamp(.82rem, .8rem + .1vw, .9rem);
  --step-0:  clamp(1.04rem, 1rem + .18vw, 1.14rem);
  --step-1:  clamp(1.2rem, 1.1rem + .4vw, 1.42rem);
  --step-2:  clamp(1.5rem, 1.3rem + .9vw, 2.05rem);
  --step-3:  clamp(1.9rem, 1.5rem + 1.7vw, 2.9rem);
  --step-4:  clamp(2.4rem, 1.7rem + 3vw, 4.4rem);

  --measure: 62ch;
  --gutter:  clamp(22px, 4vw, 46px);
  --shell:   1140px;
}

/* The site is light-ground by default. Dark sections are deliberate plates,
   not a theme toggle. The logo needs navy under it and the brand needs the
   contrast, so we choose where dark happens rather than letting the OS decide. */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--step-0);
  line-height: 1.66;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.shell { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }

h1, h2, h3 { font-family: var(--display); font-weight: 300; letter-spacing: -.022em; margin: 0; }
h1 { font-size: var(--step-4); line-height: 1.04; }
h2 { font-size: var(--step-3); line-height: 1.1; }
h3 { font-size: var(--step-1); font-weight: 500; line-height: 1.24; }
p  { margin: 0 0 1.1em; max-width: var(--measure); }

em.hi { font-style: italic; color: var(--brass); }

.label {
  font-family: var(--label);
  font-size: 11.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--brass);
}

a { color: var(--blue); text-underline-offset: 2px; }

/* --- plates: a dark section carries the mark and the cyan --- */
.plate {
  background: var(--navy-800);
  color: var(--on-navy);
}
.plate h1, .plate h2, .plate h3 { color: var(--on-navy); }
.plate p { color: var(--on-navy-2); }
/* Cards keep a paper ground even on a plate, so the plate's light-on-dark
   text colours must not reach inside them, which shipped cream-on-cream
   headings at launch and made the three card titles unreadable. */
.plate .card h1, .plate .card h2, .plate .card h3 { color: var(--ink); }
.plate .card p, .plate .card li { color: var(--ink-2); }
.plate .label { color: var(--brass-lite); }
.plate a { color: var(--cyan); }
.plate em.hi { color: var(--cyan); }

/* --- duo: the reading column, plus the thing that sits beside it ---------
 * The launch site put a 62ch measure alone inside an 1140px shell, so every
 * section left ~580px of empty canvas to its right. 62ch is the correct
 * reading measure, what was missing was anything to put next to it.
 * `.duo` is that: prose left, figure right, single column under 900px. */
.duo { display: grid; gap: 38px; align-items: start; }
.duo > .duo-text > :last-child { margin-bottom: 0; }
@media (min-width: 900px) {
  .duo { grid-template-columns: minmax(0, 56ch) minmax(0, 1fr); gap: 66px; }
  .duo.flip > .duo-text { order: 2; }
  .duo.wide { grid-template-columns: minmax(0, 46ch) minmax(0, 1fr); }
}

/* --- figures: every section needs one (CLAUDE.md hard rule) --- */
.fig { margin: 0; border: 1px solid var(--rule); background: var(--paper-2); overflow: hidden; }
.fig > img, .fig > svg { display: block; width: 100%; height: auto; }
.fig figcaption {
  font-family: var(--label); font-size: 11.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
  padding: 11px 15px; border-top: 1px solid var(--rule); background: var(--paper);
}
.plate .fig { border-color: var(--rule-navy); background: var(--navy-900); }
.plate .fig figcaption { background: transparent; border-top-color: var(--rule-navy); color: var(--on-navy-2); }

/* --- flow: a stepped schematic, drawn with the mane's node-and-trace
       vocabulary rather than an icon set. The `.gate` step is filled, because
       the human approval step is the one the studio actually sells. --- */
.flow { margin: 0; padding: 30px 30px 32px; }
.flow-step { position: relative; padding-left: 34px; }
.flow-step + .flow-step { margin-top: 19px; }
.flow-step::before {
  content: ''; position: absolute; left: 5px; top: 6px;
  width: 10px; height: 10px; border-radius: 50%;
  border: 1.5px solid var(--brass); background: var(--paper-2);
}
.flow-step::after {
  content: ''; position: absolute; left: 9.6px; top: 19px; bottom: -19px;
  width: 1px; background: var(--rule);
}
.flow-step:last-child::after { display: none; }
.flow-step b {
  display: block; font-family: var(--label); font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
  font-weight: 500; margin-bottom: 2px;
}
.flow-step span { display: block; font-size: 15px; line-height: 1.5; color: var(--ink-2); }
.flow-step.gate::before { background: var(--brass); box-shadow: 0 0 0 4px rgba(192,175,132,.16); }
.flow-step.gate span { color: var(--ink); }
.plate .flow-step::before { background: var(--navy-900); border-color: var(--brass-lite); }
.plate .flow-step::after { background: var(--rule-navy); }
.plate .flow-step b { color: var(--on-navy-2); }
.plate .flow-step span { color: var(--on-navy-2); }
.plate .flow-step.gate::before { background: var(--brass-lite); }
.plate .flow-step.gate span { color: var(--on-navy); }

/* --- figure components -------------------------------------------------
 * These are the visuals. They are CSS-rendered rather than generated images
 * on purpose: the strongest thing this studio can show a prospect is the
 * actual shape of the work, an order thread, an approvals register, a
 * before/after, and a mockup stays true when the copy changes. */

/* stats, the numbers an engagement actually moved.
 * Cell separators are drawn per-cell rather than by showing a dark container
 * through 1px gaps: with auto-fit, a 4-item grid wraps to 3+1 in a narrow
 * column, and the container-background trick renders that empty slot as a
 * solid block that reads as a broken tile. */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 1px; background: var(--paper); }
.stat { background: var(--paper); padding: 21px 19px; box-shadow: 0 0 0 1px var(--rule); }
.plate .stats { background: var(--navy-800); }
.stat b {
  display: block; font-family: var(--display); font-weight: 300;
  font-size: clamp(1.8rem, 1.3rem + 1.6vw, 2.6rem); line-height: 1;
  color: var(--ink); letter-spacing: -.022em;
}
.stat span {
  display: block; font-family: var(--label); font-size: 10.5px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); margin-top: 9px;
}
.plate .stat { background: var(--navy-900); box-shadow: 0 0 0 1px var(--rule-navy); }
.plate .stat b { color: var(--on-navy); }

/* A portrait at its natural ratio is ~630px tall in a 450px column, which
   swamps the hero it sits beside. Crop rather than scale the whole page to it. */
.fig.portrait img { max-height: 520px; object-fit: cover; object-position: center 18%; }

/* compare, what we take on, next to what we turn down */
.compare { display: grid; gap: 1px; background: var(--rule); }
@media (min-width: 640px) { .compare { grid-template-columns: 1fr 1fr; } }
.compare > div { background: var(--paper); padding: 23px 21px; }
.compare h4 {
  font-family: var(--label); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; margin: 0 0 13px; font-weight: 500;
}
.compare .yes h4 { color: var(--brass); }
.compare .no h4 { color: var(--ink-3); }
.compare ul { margin: 0; padding: 0; }
.compare li {
  list-style: none; font-size: 14px; line-height: 1.5; color: var(--ink-2);
  padding-left: 17px; position: relative; margin-bottom: 9px;
}
.compare li:last-child { margin-bottom: 0; }
.compare li::before { content: ''; position: absolute; left: 0; top: 7px; width: 7px; height: 7px; border-radius: 50%; }
.compare .yes li::before { background: var(--brass); }
.compare .no li::before { border: 1px solid var(--ink-3); }

/* chat, the order thread, roughly as the customer sees it */
.chat { padding: 19px 18px; background: var(--paper-3); }
.bubble {
  max-width: 84%; padding: 9px 12px; border-radius: 11px; font-size: 13.5px;
  line-height: 1.45; margin-bottom: 8px; color: var(--ink);
  box-shadow: 0 1px 1px rgba(9,25,48,.07);
}
.bubble.them { background: #fff; border-top-left-radius: 3px; }
.bubble.us { background: #DCF8C6; margin-left: auto; border-top-right-radius: 3px; }
.bubble.sys {
  background: transparent; border: 1px dashed var(--brass); color: var(--ink-2);
  font-family: var(--label); font-size: 10.5px; letter-spacing: .09em;
  text-transform: uppercase; max-width: 100%; text-align: center; box-shadow: none;
}
.bubble small { display: block; font-size: 10px; color: var(--ink-3); margin-top: 3px; text-align: right; }

/* tbl, an operating table, the kind a team actually runs on */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th {
  font-family: var(--label); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-3); text-align: left;
  padding: 10px 13px; border-bottom: 1px solid var(--rule); font-weight: 500;
}
.tbl td { padding: 10px 13px; border-bottom: 1px solid var(--rule); color: var(--ink-2); }
.tbl tr:last-child td { border-bottom: none; }

/* .tbl and .pill were built for paper and had never been put on a plate until
   the workshop page. Unguarded they inherited --ink-2 on navy at about 2.1:1,
   which is unreadable, and the ok pill kept its dark brass #8A6A2E on a dark
   ground. This is the inheritance hazard the brand book documents: a component
   that keeps its own background must declare its own text colours. */
.plate .tbl th { color: var(--brass-lite); border-bottom-color: var(--rule-navy); }
.plate .tbl td { color: var(--on-navy-2); border-bottom-color: var(--rule-navy); }
.plate .tbl tr:last-child td { border-bottom: none; }
.plate .pill.ok { color: var(--brass-lite); }
.plate .pill.wait { background: var(--navy-700); color: var(--on-navy-2); }
.pill {
  display: inline-block; font-family: var(--label); font-size: 9.5px;
  letter-spacing: .09em; text-transform: uppercase; padding: 3px 8px; border-radius: 20px;
}
.pill.ok { background: rgba(192,175,132,.22); color: #8A6A2E; }
.pill.wait { background: var(--paper-3); color: var(--ink-3); }

/* bars, before and after, at the same scale */
.bars { padding: 25px 23px; }
.bar { margin-bottom: 17px; }
.bar:last-child { margin-bottom: 0; }
.bar b {
  display: block; font-family: var(--label); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; font-weight: 500;
}
/* The value sits above the bar, not inside the fill, a 13% bar has no room
   for a label, and shrinking the text to fit would misrepresent the ratio. */
.bar b i { float: right; font-style: normal; color: var(--ink); letter-spacing: .04em; }
.bar .track { height: 25px; background: var(--paper-3); }
.bar .fill { height: 100%; background: var(--brass); }
.bar .fill.lite { background: transparent; border: 1px solid var(--brass); }

/* cities, three timezones, one working day */
.cities { padding: 8px 22px; }
.city { display: flex; align-items: baseline; gap: 11px; padding: 13px 0; border-bottom: 1px solid var(--rule); }
.city:last-child { border-bottom: none; }
.city b { font-family: var(--display); font-size: 18px; font-weight: 300; color: var(--ink); }
.city em { font-style: normal; font-family: var(--label); font-size: 10px; letter-spacing: .1em; color: var(--brass); }
.city span { font-size: 13px; color: var(--ink-2); margin-left: auto; text-align: right; }
.plate .city { border-bottom-color: var(--rule-navy); }
.plate .city b { color: var(--on-navy); }
.plate .city span { color: var(--on-navy-2); }

/* cal, a booking grid, shown as it will behave once T6 lands */
.cal { padding: 22px; }
.cal-head { font-family: var(--label); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 14px; }
.cal-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.slot {
  font-family: var(--label); font-size: 11.5px; text-align: center; padding: 9px 4px;
  border: 1px solid var(--rule); color: var(--ink-2); background: var(--paper);
}
.slot.busy { color: var(--ink-3); background: var(--paper-3); border-style: dashed; text-decoration: line-through; }
.slot.free { border-color: var(--brass); color: var(--ink); }

/* --- the one ornament: a hairline rule with a brass terminal node,
       lifted straight from the mane's circuit traces --- */
.trace { display: flex; align-items: center; gap: 0; margin: 2.4rem 0; }
.trace i { flex: 1; height: 1px; background: var(--rule); }
.trace b {
  width: 7px; height: 7px; border-radius: 50%;
  border: 1.5px solid var(--brass); background: transparent;
}
.plate .trace i { background: var(--rule-navy); }
.plate .trace b { border-color: var(--brass-lite); }

/* --- buttons --- */
.btn {
  display: inline-block;
  font-family: var(--label);
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  padding: 14px 28px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  transition: background .15s, color .15s;
}
.btn:hover { background: transparent; color: var(--ink); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { border-color: var(--ink); }
.plate .btn { background: var(--cyan); border-color: var(--cyan); color: var(--navy-900); }
.plate .btn:hover { background: transparent; color: var(--cyan); }
.plate .btn.ghost { background: transparent; color: var(--on-navy); border-color: var(--rule-navy); }
.plate .btn.ghost:hover { border-color: var(--on-navy); }

/* --- nav --- */
.topnav { border-bottom: 1px solid var(--rule); background: var(--paper); position: sticky; top: 0; z-index: 30; }
.topnav .shell { display: flex; align-items: center; gap: 30px; padding-block: 16px; overflow-x: auto; scrollbar-width: none; }
.topnav .shell::-webkit-scrollbar { display: none; }
.topnav a { color: var(--ink-2); text-decoration: none; font-family: var(--label); font-size: 14.5px; white-space: nowrap; }
.topnav a:hover, .topnav a.here { color: var(--brass); }

.brandmark { display: flex; align-items: center; gap: 11px; margin-right: auto; text-decoration: none; white-space: nowrap; }
.brandmark img { width: 34px; height: 34px; border-radius: 6px; display: block; }
.brandmark span { font-family: var(--display); font-size: 19px; color: var(--ink); letter-spacing: -.015em; }
.brandmark span i { font-style: italic; color: var(--brass); }

/* --- footer --- */
.foot { background: var(--navy-900); color: var(--on-navy-2); padding-block: 54px 60px; font-size: var(--step--1); }
.foot .shell { display: flex; gap: 28px; flex-wrap: wrap; align-items: center; }
.foot a { color: var(--on-navy-2); text-decoration: none; font-family: var(--label); }
.foot a:hover { color: var(--cyan); }
.foot .brandmark span { color: var(--on-navy); }
.foot .brandmark span i { color: var(--brass-lite); }

@media (max-width: 700px) {
  .topnav .shell { gap: 20px; }
  .brandmark span { font-size: 17px; }
  /* The nav scrolls sideways with its scrollbar hidden, so on a phone the items
     past the fold had nothing to announce them. A fade on the trailing edge is
     the affordance. Kept off the sticky container itself, which would clip. */
  .topnav { position: sticky; }
  .topnav::after {
    content: ''; position: absolute; top: 0; right: 0; bottom: 1px; width: 42px;
    pointer-events: none;
    background: linear-gradient(to right, rgba(251,250,247,0), var(--paper));
  }
}

/* --- The mark (T1, 2026-08-03) ---
 * ONE mark at every size: assets/mark-tight-*.png (512/180/128/64/32).
 * Never ship mark.png directly, the source has 216px of dead navy on every
 * side of a 1024 canvas (21% per edge) and renders the lion undersized.
 * mark-tight-* is cropped to the ink with a 7% margin.
 * It softens at 32 and below. That is accepted: the circuit mane is what makes
 * this an AI studio's lion rather than a generic one, and a tab is identified
 * by colour and silhouette, not fine detail. A second head-only variant was
 * built and deliberately dropped, one mark is worth more than sharp favicons.
 */

/* ======================================================================
   WEB-5, the revamp layer.
   Everything above this line is the original Bureau system and stays.
   Everything below is what the four location pages, the splash, the
   photographic plates and the assistant needed.
   ====================================================================== */

/* --- photographs -------------------------------------------------------
 * Every photograph on this site is a long exposure. That is the whole art
 * direction: one sharp still subject, everything else drawn as light over
 * several seconds. It matches the mark, it survives being cropped hard,
 * and it means forty-two images read as one set rather than forty-two. */
.fig.pic { background: var(--navy-900); border-color: var(--rule); }
.fig.pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fig.pic.tall img { aspect-ratio: 4 / 5; }
.fig.pic.wide img { aspect-ratio: 3 / 2; }

/* --- image hero --------------------------------------------------------
 * A full-bleed long exposure behind the first screen. The scrim is two
 * gradients rather than one flat wash: a strong navy from the left so the
 * text column always clears AA regardless of what the photograph does
 * there, plus a softer bottom lift so the nav and the scroll cue hold. */
/* [JON, 2026-08-26] "Remove busy images behind text" and "text on both sides of
   the screen is not allowed". The hero puts its words on flat navy and stands the
   picture beside them. Scoped with :has so the heroes that lay themselves out
   with .hero-cols are left alone; applying it to every .shell squeezed their
   figure to 2px wide. */
.imghero { background: var(--navy-900); color: var(--on-navy); overflow: hidden; }
.imghero > .shell { padding-block: clamp(52px, 7vw, 88px) clamp(44px, 6vw, 72px); }
.imghero > .shell:has(> .hero-copy) {
  display: grid; grid-template-columns: 1fr; gap: 26px; align-items: center;
}
@media (min-width: 900px) {
  .imghero > .shell:has(> .hero-copy) { grid-template-columns: 1.02fr .98fr; gap: 46px; }
}
.imghero .bg { order: 2; align-self: stretch; display: flex; }
.imghero .bg img {
  width: 100%; height: 100%; max-height: 460px; object-fit: cover; display: block;
  border-radius: 3px;
}
.imghero .bg::after { content: none; }
.imghero .hero-copy { order: 1; min-width: 0; }
.imghero .hero-copy .hero-cols { display: block; }
.imghero .hero-copy .hero-cols > * + * { margin-top: 26px; }
.imghero .bg:has(.herovid) { align-self: center; }
.imghero .bg .herovid { width: 100%; height: auto; aspect-ratio: 16 / 9; display: block;
  border-radius: 3px; background: #000; }
.imghero h1, .imghero h2 { color: var(--on-navy); }
.imghero .lede { color: var(--on-navy-2); }
.imghero .label { color: var(--brass-lite); }
.imghero .btn { background: var(--cyan); border-color: var(--cyan); color: var(--navy-900); }
.imghero .btn:hover { background: transparent; color: var(--cyan); }
.imghero .btn.ghost { background: transparent; color: var(--on-navy); border-color: rgba(239,237,230,.34); }
.imghero .btn.ghost:hover { border-color: var(--on-navy); }
@media (min-width: 900px) { .imghero .hero-cols { display: grid; grid-template-columns: minmax(0, 48ch) minmax(0, 1fr); gap: 66px; align-items: center; } }

/* Below the two-column breakpoint the headline runs the full width, so it sits
   over the bright right-hand side of the exposure that the 100deg gradient
   deliberately leaves clear. A long lede then crosses the light trails and stops
   being readable. Under 900px there is no side-by-side layout left to protect,
   so the scrim goes flat and vertical instead. */
@media (max-width: 899px) {
  .imghero > .bg::after {
    background: linear-gradient(180deg, rgba(6,17,31,.90) 0%, rgba(6,17,31,.82) 50%, rgba(6,17,31,.90) 100%);
  }
}

/* --- image plate -------------------------------------------------------
 * A section that breaks the 1140px shell entirely and runs edge to edge.
 * Alternating this against the tight reading measure is the single biggest
 * change to how the page feels at 1920, where the old build left most of
 * the canvas empty. */
.plate.pic { position: relative; background: var(--navy-900); }
.plate.pic > .bg { position: absolute; inset: 0; z-index: 0; }
.plate.pic > .bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plate.pic > .bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(96deg, rgba(6,17,31,.95) 0%, rgba(6,17,31,.84) 44%, rgba(6,17,31,.46) 100%);
}
.plate.pic > .shell { position: relative; z-index: 1; }

/* --- the locations grid ------------------------------------------------
 * Four cities, each with its own long exposure and a clock that is running
 * rather than printed. The clock is the point: it is the cheapest possible
 * proof that somebody is awake somewhere. */
/* wscard, one workshop in the index. The whole card is the link. Kept on paper
   deliberately: a plate variant would need its own colour declarations, which is
   the inheritance hazard the brand book documents. */
.wsgrid { display: grid; gap: 2px; background: var(--rule); border: 1px solid var(--rule); margin-top: 34px; }
@media (min-width: 860px) { .wsgrid.w2 { grid-template-columns: 1fr 1fr; } }
.wscard { background: var(--paper); display: block; text-decoration: none; padding-bottom: 24px; }
.wscard img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.wscard .in { padding: 22px 24px 0; }
.wscard .when {
  font-family: var(--label); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--brass);
}
.wscard h3 {
  font-family: var(--display); font-weight: 300; font-size: var(--step-1);
  color: var(--ink); margin: 11px 0 9px; letter-spacing: -.018em; line-height: 1.16;
}
.wscard p { font-size: 13.5px; color: var(--ink-2); margin: 0; max-width: 46ch; }
.wscard .meta {
  margin-top: 15px; font-family: var(--label); font-size: 11.5px; color: var(--ink-3);
  display: flex; gap: 8px; flex-wrap: wrap;
}
.wscard .meta i { font-style: normal; color: var(--rule); }
/* A lone card would otherwise run the full shell width with a 16:9 image, which
   reads as a second hero rather than as a listing. Side by side instead. */
@media (min-width: 760px) {
  .wscard:only-child { display: grid; grid-template-columns: 46% 1fr; padding-bottom: 0; }
  .wscard:only-child img { height: 100%; aspect-ratio: auto; }
  .wscard:only-child .in { padding: 32px 32px 34px; align-self: center; }
}
.wscard:hover h3 { color: var(--blue); }
.wscard.is-past { opacity: .72; }
.wscard.is-past .when { color: var(--ink-3); }

.citygrid { display: grid; gap: 2px; background: var(--rule); border: 1px solid var(--rule); margin-top: 38px; }
@media (min-width: 760px) { .citygrid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1180px) { .citygrid.c4 { grid-template-columns: repeat(4, 1fr); } }
.citycard { position: relative; display: block; text-decoration: none; background: var(--navy-900); min-height: 310px; overflow: hidden; }
.citycard img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.2,.7,.3,1), filter .5s; }
.citycard::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(6,17,31,.94) 12%, rgba(6,17,31,.58) 52%, rgba(6,17,31,.26) 100%);
  transition: background .45s;
}
.citycard .body { position: relative; z-index: 2; padding: 24px 22px; display: flex; flex-direction: column; justify-content: flex-end; min-height: 310px; }
.citycard b { font-family: var(--display); font-weight: 300; font-size: 1.62rem; color: var(--on-navy); letter-spacing: -.02em; display: block; }
.citycard .region { font-family: var(--label); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--brass-lite); margin-bottom: 9px; }
.citycard .role { font-size: 14px; color: var(--on-navy-2); margin-top: 8px; line-height: 1.5; }
.citycard .clock {
  font-family: var(--mono); font-size: 12.5px; color: var(--cyan);
  margin-top: 13px; padding-top: 12px; border-top: 1px solid rgba(239,237,230,.16);
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
}
.citycard .clock span { font-family: var(--label); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--on-navy-2); }
.citycard:hover img, .citycard:focus-visible img { transform: scale(1.045); }
.citycard:hover::after, .citycard:focus-visible::after { background: linear-gradient(to top, rgba(6,17,31,.9) 8%, rgba(6,17,31,.42) 58%, rgba(9,122,214,.20) 100%); }
.citycard:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

/* --- person card -------------------------------------------------------
 * Rendered on the Harare page from the SAME KB node the team page renders.
 * Jon was explicit that his information is not to be duplicated per
 * location, so this is one node with two renderings, never a second copy. */
.person { display: flex; gap: 22px; align-items: flex-start; border: 1px solid var(--rule); background: var(--paper); padding: 22px; }
.person img { width: 104px; height: 128px; object-fit: cover; object-position: center 18%; flex: none; }
.person h3 { margin: 0 0 3px; }
.person .role { font-family: var(--label); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--brass); margin-bottom: 10px; }
.person p { font-size: 14.5px; color: var(--ink-2); margin: 0 0 12px; }
.plate .person { background: var(--navy-900); border-color: var(--rule-navy); }
.plate .person p { color: var(--on-navy-2); }
.plate .person .role { color: var(--brass-lite); }
@media (max-width: 460px) { .person { flex-direction: column; } .person img { width: 100%; height: 190px; object-position: center 20%; } }

/* --- contact block -----------------------------------------------------
 * One component, used on the contact page and on all four location pages,
 * so a number can never be right in one place and stale in another. */
.contactblock { border: 1px solid var(--rule); background: var(--paper-2); }
.contactline { display: flex; gap: 14px; align-items: baseline; padding: 15px 20px; border-bottom: 1px solid var(--rule); flex-wrap: wrap; }
.contactline:last-child { border-bottom: none; }
.contactline b { font-family: var(--label); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; min-width: 128px; }
.contactline a, .contactline span.val { font-family: var(--mono); font-size: 15px; color: var(--ink); text-decoration: none; letter-spacing: -.01em; }
.contactline a:hover { color: var(--blue); text-decoration: underline; }
.plate .contactblock { background: var(--navy-900); border-color: var(--rule-navy); }
.plate .contactline { border-bottom-color: var(--rule-navy); }
.plate .contactline b { color: var(--on-navy-2); }
.plate .contactline a, .plate .contactline span.val { color: var(--on-navy); }
.plate .contactline a:hover { color: var(--cyan); }

/* --- scroll entrance ---------------------------------------------------
 * Sections rise and settle as they arrive. Staggered per child so a stat
 * row reads as a phrase rather than a block landing at once. */
.reveal { opacity: 0; transform: translateY(19px); transition: opacity .78s cubic-bezier(.22,.68,.3,1), transform .78s cubic-bezier(.22,.68,.3,1); }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .citycard img { transition: none; }
}
/* No-JS must never leave a page invisible. The observer adds .js to <html>
   on boot; without it every .reveal is simply visible. */
html:not(.js) .reveal { opacity: 1; transform: none; }

/* --- splash ------------------------------------------------------------
 * First visit only. The homepage is fully rendered underneath, so crawlers
 * and no-JS visitors get the site rather than a title card. */
.splash {
  position: fixed; inset: 0; z-index: 90; background: var(--navy-900);
  display: flex; align-items: center; justify-content: center;
  transition: opacity .82s ease, visibility .82s;
}
.splash[hidden] { display: none; }
.splash.out { opacity: 0; visibility: hidden; pointer-events: none; }
.splash video, .splash .poster {
  position: absolute; left: 0; right: 0; top: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 34%;
}
/* On a portrait phone `cover` crops a 16:9 clip so hard that the mane is cut
   off both sides. Contain keeps the whole mark, sitting in the upper half. */
@media (max-width: 700px), (orientation: portrait) {
  .splash video, .splash .poster { height: 62%; object-fit: contain; object-position: center center; }
}
/* The mark resolves in the centre of the clip, so the centre is the one place
   type cannot go. A radial veil darkened the edges and left the wordmark
   sitting on the brightest cyan in the frame, unreadable at every size. The
   scrim is now vertical and the copy lives under it. */
.splash .veil {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 78% 58% at 50% 38%, rgba(6,17,31,0) 40%, rgba(6,17,31,.55) 100%),
    linear-gradient(to bottom, rgba(6,17,31,.34) 0%, rgba(6,17,31,0) 22%, rgba(6,17,31,.42) 52%, rgba(6,17,31,.93) 74%, #06111F 100%);
}
.splash .inner {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: clamp(96px, 19vh, 172px);
  text-align: center; padding: 0 26px;
}
.splash .wordmark {
  font-family: var(--display); font-weight: 300; color: var(--on-navy);
  font-size: clamp(1.7rem, 1.1rem + 2.6vw, 3.3rem); letter-spacing: -.022em; line-height: 1.1;
  opacity: 0; animation: splashIn 1.5s 2.5s cubic-bezier(.2,.7,.3,1) forwards;
}
.splash .wordmark i { font-style: italic; color: var(--cyan); }
.splash .sub {
  font-family: var(--label); font-size: 11.5px; letter-spacing: .19em; text-transform: uppercase;
  color: var(--brass-lite); margin-top: 16px;
  opacity: 0; animation: splashIn 1.5s 3.1s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes splashIn { from { opacity: 0; transform: translateY(11px); } to { opacity: 1; transform: none; } }
.splash .skip {
  position: absolute; z-index: 3; bottom: 30px; left: 50%; transform: translateX(-50%);
  font-family: var(--label); font-size: 11.5px; letter-spacing: .15em; text-transform: uppercase;
  color: var(--on-navy-2); background: transparent; border: 1px solid rgba(239,237,230,.28);
  padding: 11px 22px; cursor: pointer; border-radius: 2px;
}
.splash .skip:hover { color: var(--navy-900); background: var(--cyan); border-color: var(--cyan); }
.splash .skip:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
/* Reduced motion gets the poster and the copy immediately: the final frame
   of the clip is the resolved mark, so nothing is lost but the reveal. */
@media (prefers-reduced-motion: reduce) {
  .splash video { display: none; }
  .splash .wordmark, .splash .sub { opacity: 1; animation: none; }
}
body.splashing { overflow: hidden; }

/* --- the assistant -----------------------------------------------------
 * The platform's own widget in an iframe. The studio sells chatbots, so
 * not having one here would argue against the product. */
.bot-launch {
  position: fixed; z-index: 70; right: 22px; bottom: 22px;
  display: flex; align-items: center; gap: 10px;
  font-family: var(--label); font-size: 14px; font-weight: 500;
  background: var(--navy-800); color: var(--on-navy);
  border: 1px solid var(--rule-navy); border-radius: 999px;
  padding: 13px 21px 13px 17px; cursor: pointer;
  box-shadow: 0 8px 28px rgba(6,17,31,.3);
  transition: transform .2s, background .2s;
}
.bot-launch:hover { transform: translateY(-2px); background: var(--navy-700); }
.bot-launch:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
.bot-launch svg { width: 19px; height: 19px; flex: none; stroke: var(--cyan); }
.bot-panel {
  position: fixed; z-index: 71; right: 22px; bottom: 22px;
  width: 396px; height: min(624px, calc(100vh - 44px));
  background: var(--paper); border: 1px solid var(--rule-navy); border-radius: 12px;
  box-shadow: 0 22px 64px rgba(6,17,31,.36); overflow: hidden;
  display: flex; flex-direction: column;
  opacity: 0; transform: translateY(14px) scale(.985); pointer-events: none;
  transition: opacity .26s, transform .26s;
}
.bot-panel.open { opacity: 1; transform: none; pointer-events: auto; }
.bot-head {
  display: flex; align-items: center; gap: 9px; padding: 8px 12px;
  background: var(--navy-900); color: var(--on-navy); flex: none;
}
.bot-head img { border-radius: 4px; display: block; }
.bot-head .ai { font-family: var(--label); font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--navy-900); background: var(--brass-lite); padding: 3px 7px; border-radius: 3px; }
.bot-head button { margin-left: auto; background: none; border: none; color: var(--on-navy-2); cursor: pointer; font-size: 21px; line-height: 1; padding: 2px 5px; }
.bot-head button:hover { color: var(--cyan); }
.bot-panel iframe { flex: 1; width: 100%; border: 0; display: block; }
/* At 375 a 396px panel would hang off the screen. Full screen, always with
   a visible close. */
@media (max-width: 560px) {
  .bot-panel { right: 0; bottom: 0; width: 100vw; height: 100dvh; border-radius: 0; border: none; }
  .bot-launch { right: 14px; bottom: 14px; padding: 12px 18px 12px 15px; }
}
body.bot-open { overflow: hidden; }
@media (min-width: 561px) { body.bot-open { overflow: auto; } }

/* --- 404 --------------------------------------------------------------- */
.notfound { min-height: 62vh; display: flex; align-items: center; }

/* --- misc revamp bits -------------------------------------------------- */
.scrollcue {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 40px;
  font-family: var(--label); font-size: 10.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--on-navy-2);
}
.scrollcue i { display: block; width: 1px; height: 30px; background: linear-gradient(to bottom, var(--brass-lite), transparent); }
.eyebrow-row { display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: center; }
.tzstrip { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.tzchip {
  font-family: var(--label); font-size: 11px; letter-spacing: .07em;
  border: 1px solid var(--rule); padding: 7px 12px; color: var(--ink-2); background: var(--paper);
}
.tzchip b { font-family: var(--mono); color: var(--ink); font-weight: 400; margin-left: 7px; }
.plate .tzchip { border-color: var(--rule-navy); background: transparent; color: var(--on-navy-2); }
.plate .tzchip b { color: var(--cyan); }

/* A three-card or two-card grid inside a navy plate was rendering the unused
   4th column as a solid paper block, which read as a broken tile. Column count
   follows the card count. */
@media (min-width: 1180px) {
  .citygrid.c3 { grid-template-columns: repeat(3, 1fr); }
  .citygrid.c2 { grid-template-columns: repeat(2, 1fr); }
}


/* Small uppercase labels and links use --brass, which measures 3.39:1 on paper at
   11.5px and fails 4.5:1. A darker tone for that use only. */
.label, .more, a.piccard .more, .wcard .label, .wcard .more { color: #775C24; }
.plate .label, .plate .more, .imghero .label { color: var(--brass-lite); }
.plate .piccard { background: var(--paper); }
.plate .piccard h3 { color: var(--ink); }
.plate .piccard p { color: var(--ink-2); }
.plate .piccard .label, .plate .piccard .more { color: #775C24; }

/* The picture plate follows the hero rule: words on flat navy, picture beside. */
.plate.pic > .shell { display: grid; grid-template-columns: 1fr; gap: 26px; align-items: center; }
@media (min-width: 900px) { .plate.pic > .shell { grid-template-columns: .98fr 1.02fr; gap: 46px; } }
.plate.pic .bg { position: static; inset: auto; order: 1; }
.plate.pic .bg::after { content: none; }
.plate.pic .bg img { width: 100%; height: 100%; max-height: 420px; object-fit: cover;
  display: block; border-radius: 3px; }
.plate.pic .hero-copy { order: 2; min-width: 0; }

/* A duo with nothing to pair against is one column, not a half-width paragraph
   with dead space beside it. [JON, 2026-08-27] broad UI pass. */
.duo:not(:has(> * + *)) { grid-template-columns: 1fr !important; }
.duo:not(:has(> * + *)) > * { max-width: var(--measure, 68ch); }


/* Four drawn clock faces, hands set from real local time and moving. Fills the
   half of the location prose block that was empty. [JON, 2026-08-27] */
.clocks { margin: 0; }
.clockgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px;
  background: var(--rule); border: 1px solid var(--rule); }
.clk { background: var(--paper); padding: 20px 14px; text-align: center; }
.clk.on { background: var(--paper-2); }
.clk svg { width: 62px; height: 62px; display: block; margin: 0 auto 10px; }
.clk-face { fill: none; stroke: var(--rule); stroke-width: 1.5; }
.clk.on .clk-face { stroke: #775C24; }
.clk-tick { stroke: var(--ink-3); stroke-width: 1; }
.clk-tick.q { stroke: var(--ink-2); stroke-width: 1.8; }
.clk-h, .clk-m { stroke: var(--ink); stroke-width: 2.4; stroke-linecap: round;
  transform-origin: 32px 32px; transition: transform .6s cubic-bezier(.2,.7,.3,1); }
.clk-m { stroke-width: 1.6; stroke: var(--ink-2); }
.clk.on .clk-h, .clk.on .clk-m { stroke: #775C24; }
.clk-pin { fill: var(--ink); }
.clk.on .clk-pin { fill: #775C24; }
.clk b { display: block; font-family: var(--label); font-size: 12.5px; color: var(--ink); }
.clk span { display: block; font-family: var(--mono); font-size: 12px; color: var(--ink-2); margin-top: 2px; }
.clocks figcaption { font-size: 13px; color: var(--ink-2); padding-top: 10px; }


/* The engagement flow draws itself. A rail grows down the left, then each step
   lands in turn. Nothing moves until the figure is on screen, and nothing moves
   at all for a reader who has asked for less motion. [JON, 2026-08-27] */
.flow.anim { position: relative; }
.flow-rail { position: absolute; left: 11px; top: 8px; bottom: 8px; width: 2px;
  background: var(--rule); overflow: hidden; }
@media (min-width: 720px) { .flow-rail { display: none; } }
.flow-rail i { display: block; width: 100%; height: 100%; background: #775C24;
  transform: scaleY(0); transform-origin: top; transition: transform 1.1s cubic-bezier(.4,0,.2,1); }
.flow.anim.drawn .flow-rail i { transform: scaleY(1); }
.flow.anim .flow-step { opacity: 0; transform: translateY(14px);
  transition: opacity .55s ease, transform .55s cubic-bezier(.2,.7,.3,1);
  transition-delay: calc(var(--i, 0) * 160ms + 220ms); }
.flow.anim.drawn .flow-step { opacity: 1; transform: none; }
.flow.anim .fsic svg { transition: transform .5s cubic-bezier(.2,.7,.3,1);
  transition-delay: calc(var(--i, 0) * 160ms + 320ms); transform: scale(.7); }
.flow.anim.drawn .fsic svg { transform: scale(1); }
@media (prefers-reduced-motion: reduce) {
  .flow.anim .flow-step, .flow.anim .fsic svg { opacity: 1; transform: none; transition: none; }
  .flow-rail i { transform: scaleY(1); transition: none; }
}
