/* =============================================================================
   L'AGENCE — app.css
   -----------------------------------------------------------------------------
   ORIGIN
   Layout, spacing and component rules below were ported from
   reference/mockups/website-v2.1 (single <style> block, 9,182 bytes,
   byte-identical across all eight mockup pages), then expanded for
   readability and grouped with section comments.

   COLOUR IS NO LONGER FROM THE MOCKUP
   2026-08-26: the :root palette was replaced to match Brand Book v9.7,
   page 02.1 / CORE NEUTRAL SYSTEM. The v2.1 mockup predates that page and
   its warm neutrals (#f6f3ee, #23201d, #d8d1c8, #ece7df, #e27a36) are no
   longer valid. The Brand Book is the colour authority; this file is not.

   Four tokens had no direct Brand Book equivalent and are derived defaults,
   marked inline below: --paper2, --ink, --line, --orange2.

   KNOWN DIVERGENCE
   assets/img/*.svg fill the apostrophe #E36A2C, while the Agency signal in
   the Brand Book is #C75B2A. Deliberately left unresolved. Do not "fix"
   either side without a decision from the brand owner.

   WHAT IS STILL FROZEN
   Everything that is not colour. Do not tidy layout, spacing, type scale or
   component values here — that part is still the visual contract.

   Approved-design changes live in the ADDITIONS LAYER at the foot of this
   file and are individually labelled with the audit reference that
   justifies them.
   ============================================================================= */


:root {
  /* Brand Book v9.7 — 02.1 Core Neutral System. Do not add values that are
     not on the neutral page or the signal page. */

  /* Dark surfaces */
  --black:#0a0a0a;      /* OBSIDIAN  — stage */
  --charcoal:#141414;   /* CHARCOAL  — base */
  --graphite:#1f1f1f;   /* GRAPHITE  — surface */
  --edge:#2a2a2a;       /* EDGE      — line */

  /* Light + type neutrals */
  --paper:#f5f5f3;      /* SOFT WHITE */
  --white:#f5f5f3;      /* SOFT WHITE (alias, kept so existing rules resolve) */
  --paper2:#f5f5f3;     /* DERIVED. Was #ece7df. The book has no second light
                           surface, so this now equals --paper. To bring back
                           section contrast, use --charcoal, not a second cream. */
  --ink:#141414;        /* DERIVED. Was #23201d. Charcoal as dark type on light. */
  --line:#b8b5ae;       /* DERIVED. Was #d8d1c8. The book's only line value is
                           EDGE #2a2a2a, which is dark-mode only, so PLATINUM
                           stands in for light-surface hairlines. */
  --muted:#89867f;      /* SLATE — captions, descriptors, tertiary type.
                           ~3.2:1 on --paper. Fails WCAG AA for body copy.
                           Keep off running text. */

  /* Signal — Agency. Overridden per vertical by inc/tokens.php. */
  --orange:#c75b2a;
  --orange2:#c75b2a;    /* DERIVED. Was #e27a36. A second orange is not in the
                           system; kept as a token only so old rules resolve. */
}


/* ---------------------------------------------------------------------------
   RESET & BASE
   --------------------------------------------------------------------------- */

* {
  box-sizing:border-box;
}

html {
  scroll-behavior:smooth;
  background:var(--charcoal);   /* A17.4 — see foot of file. Dark by default. */
}

body {
  margin:0;
  background:var(--charcoal);   /* A17.4 — was var(--paper). Sections paint their own ground. */
  color:var(--ink);
  font-family:Inter,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}

a {
  color:inherit;
}

img {
  display:block;
  max-width:100%;
}

.serif {
  font-family:"Playfair Display","Iowan Old Style",Baskerville,"Times New Roman",serif;
  letter-spacing:-.035em;
}


/* ---------------------------------------------------------------------------
   LAYOUT CONTAINER
   --------------------------------------------------------------------------- */

.wrap {
  width:min(1120px,calc(100% - 40px));
  margin:0 auto;
}


/* ---------------------------------------------------------------------------
   NAVIGATION
   --------------------------------------------------------------------------- */

.nav {
  position:fixed;
  z-index:30;
  top:16px;
  left:50%;
  transform:translateX(-50%);
  width:min(1120px,calc(100% - 32px));
  height:58px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:0 18px;
  border:1px solid rgba(255,255,255,.16);
  border-radius:999px;
  background:rgba(16,16,16,.80);
  backdrop-filter:blur(18px);
}

.logo {
  display:flex;
  align-items:center;
  gap:7px;
  color:#fff;
  text-decoration:none;
  font-family:Georgia,serif;
  font-size:22px;
}

.logo i {
  display:inline-block;
  width:8px;
  height:18px;
  border-radius:10px;
  background:var(--orange);
  transform:skew(-16deg);
}

.navlinks {
  display:flex;
  gap:22px;
  align-items:center;
}

.navlinks a {
  color:#d9d4cd;
  text-decoration:none;
  font-size:11px;
  font-weight:800;
  letter-spacing:.09em;
  text-transform:uppercase;
}

.navlinks .cta {
  background:var(--orange);
  color:#fff;
  padding:10px 16px;
  border-radius:999px;
}

.menu {
  display:none;
  background:none;
  border:0;
  color:white;
  font-size:24px;
}

.mobile {
  display:none;
  position:fixed;
  top:86px;
  left:16px;
  right:16px;
  z-index:29;
  background:#111;
  border:1px solid #2b2b2b;
  border-radius:22px;
  padding:20px;
}

.mobile.open {
  display:grid;
  gap:14px;
}

.mobile a {
  color:#fff;
  text-decoration:none;
  text-transform:uppercase;
  font-size:12px;
  font-weight:800;
  letter-spacing:.08em;
}


/* ---------------------------------------------------------------------------
   EYEBROW / KICKER
   --------------------------------------------------------------------------- */

.kicker {
  font-size:11px;
  font-weight:900;
  letter-spacing:.17em;
  text-transform:uppercase;
  color:var(--orange);
}


/* ---------------------------------------------------------------------------
   HERO
   --------------------------------------------------------------------------- */

.hero {
  min-height:94vh;
  background:var(--charcoal);
  color:#fff;
  padding:120px 0 72px;
  position:relative;
  overflow:hidden;
}

.hero:before {
  content:"";
  position:absolute;
  inset:0;
  background:linear-gradient(90deg,rgba(15,15,15,.92) 0%,rgba(15,15,15,.64) 50%,rgba(15,15,15,.25) 100%),var(--hero) center/cover no-repeat;
}

.hero>.wrap {
  position:relative;
  z-index:2;
  opacity:1;
  visibility:visible;
  display:grid;
  grid-template-columns:1fr .82fr;
  gap:58px;
  align-items:end;
  min-height:calc(94vh - 190px);
}

h1 {
  font-size:clamp(58px,8vw,112px);
  line-height:.79;
  margin:22px 0 26px;
  text-transform:uppercase;
}

.hero p {
  font-size:19px;
  line-height:1.5;
  color:#d4cec7;
  max-width:640px;
  margin:0;
}

.hero-panel {
  border:1px solid rgba(255,255,255,.16);
  border-radius:30px;
  padding:26px;
  background:rgba(15,15,15,.46);
  backdrop-filter:blur(12px);
}

.hero-panel h2 {
  font-size:36px;
  line-height:.96;
  margin:0 0 25px;
  text-transform:uppercase;
}

.mini {
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
}

.mini-card {
  border:1px solid rgba(255,255,255,.11);
  padding:16px;
  border-radius:18px;
  background:rgba(255,255,255,.03);
}

.mini-card b {
  display:block;
  color:var(--orange);
  font-size:11px;
  letter-spacing:.11em;
  text-transform:uppercase;
  margin-bottom:9px;
}

.mini-card span {
  font-size:13px;
  line-height:1.35;
  color:#c4beb7;
}

.actions {
  display:flex;
  gap:12px;
  flex-wrap:wrap;
  margin-top:30px;
}

.btn {
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-height:48px;
  padding:0 20px;
  border-radius:999px;
  border:1px solid rgba(255,255,255,.3);
  text-decoration:none;
  font-size:11px;
  font-weight:900;
  letter-spacing:.10em;
  text-transform:uppercase;
}

.btn.primary {
  background:var(--orange);
  border-color:var(--orange);
  color:#fff;
}

.btn.dark {
  background:var(--black);
  border-color:var(--black);
  color:#fff;
}


/* ---------------------------------------------------------------------------
   MARQUEE BAND
   --------------------------------------------------------------------------- */

.orange-band {
  overflow:hidden;
  background:var(--orange);
  color:#fff;
  padding:13px 0;
  font-weight:900;
  font-size:11px;
  letter-spacing:.15em;
  text-transform:uppercase;
  white-space:nowrap;
}

.orange-band div {
  width:max-content;
  animation:marquee 28s linear infinite;
}

@keyframes marquee {
  to {
    transform:translateX(-50%);
  }
}


/* ---------------------------------------------------------------------------
   SECTIONS
   --------------------------------------------------------------------------- */

.section {
  padding:105px 0;
  opacity:1;
  visibility:visible;
}

.light {
  background:var(--paper);
  color:var(--ink);
}

.dark {
  background:var(--charcoal);
  color:#fff;
}

.section-title {
  font-size:clamp(48px,6vw,84px);
  line-height:.89;
  margin:20px 0 24px;
  text-transform:uppercase;
}

.section-title.small {
  font-size:clamp(42px,5vw,64px);
}

.section-lead {
  font-size:18px;
  line-height:1.52;
  max-width:700px;
  color:var(--muted);
}

.dark .section-lead {
  color:#c6c0b9;
}

.section-head {
  display:grid;
  grid-template-columns:1fr .72fr;
  gap:64px;
  align-items:end;
  margin-bottom:54px;
}


/* ---------------------------------------------------------------------------
   WORK CARDS
   --------------------------------------------------------------------------- */

.work-grid {
  display:grid;
  grid-template-columns:1.25fr .75fr;
  gap:16px;
}

.work-card {
  min-height:500px;
  border-radius:30px;
  padding:28px;
  position:relative;
  overflow:hidden;
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  text-decoration:none;
  background:#171615;
  color:#fff;
  border:1px solid #2c2a28;
}

.work-card.image:before {
  content:"";
  position:absolute;
  inset:0;
  background:linear-gradient(0deg,rgba(0,0,0,.80),rgba(0,0,0,.10)),var(--img) center/cover no-repeat;
}

.work-card>* {
  position:relative;
  z-index:2;
}

.work-card small {
  color:var(--orange);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  font-weight:900;
}

.work-card h3 {
  font-size:46px;
  line-height:.90;
  margin:0 0 16px;
  text-transform:uppercase;
}

.work-card p {
  max-width:430px;
  line-height:1.45;
  color:#ccc6bf;
}

.arrow {
  position:absolute;
  right:25px;
  top:25px;
  width:44px;
  height:44px;
  border-radius:50%;
  display:grid;
  place-items:center;
  border:1px solid rgba(255,255,255,.35);
  z-index:2;
}


/* ---------------------------------------------------------------------------
   CAPABILITY TILES
   --------------------------------------------------------------------------- */

.capabilities {
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:14px;
  margin-top:44px;
}

.cap {
  border:1px solid rgba(255,255,255,.13);
  border-radius:24px;
  padding:23px;
  background:#1c1b19;
}

.cap b {
  display:block;
  color:var(--orange);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  margin-bottom:22px;
}

.cap h3 {
  font-size:29px;
  line-height:.95;
  margin:0 0 15px;
  text-transform:uppercase;
}

.cap p {
  color:#c4beb7;
  line-height:1.45;
  margin:0;
}


/* ---------------------------------------------------------------------------
   SPLIT + BROWSER MOCK
   --------------------------------------------------------------------------- */

.split {
  display:grid;
  grid-template-columns:.92fr 1.08fr;
  gap:58px;
  align-items:center;
}

.mock {
  border-radius:34px;
  border:1px solid rgba(255,255,255,.16);
  background:#0b0b0b;
  padding:28px;
  min-height:430px;
  box-shadow:0 28px 80px rgba(0,0,0,.16);
}

.browserbar {
  height:38px;
  border-radius:14px;
  background:#171615;
  margin-bottom:45px;
}

.mock h3 {
  font-size:54px;
  line-height:.87;
  margin:0 0 26px;
  text-transform:uppercase;
  color:#fff;
}

.mock p {
  color:#bdb7b0;
  max-width:390px;
  line-height:1.5;
}


/* ---------------------------------------------------------------------------
   PROCESS STRIP
   --------------------------------------------------------------------------- */

.process {
  display:grid;
  grid-template-columns:repeat(6,1fr);
  gap:12px;
  margin-top:46px;
}

.step {
  padding-top:18px;
  border-top:2px solid var(--line);
}

.step b {
  display:block;
  color:var(--orange);
  font-size:11px;
  margin-bottom:16px;
}

.step span {
  font-weight:900;
  font-size:12px;
  letter-spacing:.08em;
  text-transform:uppercase;
}


/* ---------------------------------------------------------------------------
   CONTACT & FORM
   --------------------------------------------------------------------------- */

.contact {
  padding:110px 0;
  background:var(--charcoal);
  color:#fff;
}

.contactbox {
  display:grid;
  grid-template-columns:1fr .9fr;
  gap:50px;
  align-items:start;
  border:1px solid rgba(255,255,255,.14);
  border-radius:34px;
  padding:36px;
  background:#111;
}

form {
  display:grid;
  gap:12px;
}

input, select, textarea {
  width:100%;
  background:#0a0a0a;
  border:1px solid #2c2a28;
  border-radius:14px;
  color:#fff;
  padding:15px 16px;
  font:inherit;
}

textarea {
  min-height:120px;
}

.submit {
  border:0;
  background:var(--orange);
  color:#fff;
  border-radius:999px;
  padding:15px 20px;
  font-weight:900;
  letter-spacing:.12em;
  text-transform:uppercase;
}


/* ---------------------------------------------------------------------------
   FOOTER
   --------------------------------------------------------------------------- */

.footer {
  background:var(--black);   /* OBSIDIAN. was #0c0c0c */
  color:var(--muted);        /* SLATE. was #958f88 */
  padding:30px 0;
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
}

.footer .wrap {
  display:flex;
  justify-content:space-between;
  gap:20px;
}


/* ---------------------------------------------------------------------------
   SERVICE TILES
   --------------------------------------------------------------------------- */

.service-grid {
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:16px;
  margin-top:46px;
}

.service {
  border-radius:26px;
  border:1px solid var(--line);
  padding:28px;
  background:#fff;
}

.service h3 {
  font-size:34px;
  line-height:.95;
  margin:12px 0;
  text-transform:uppercase;
}

.service p {
  color:#6f6962;
  line-height:1.5;
}


/* ---------------------------------------------------------------------------
   CASE STUDY STORY
   --------------------------------------------------------------------------- */

.story {
  display:grid;
  grid-template-columns:.68fr 1.32fr;
  gap:18px;
  margin-top:52px;
}

.story-nav {
  position:sticky;
  top:100px;
  align-self:start;
  border-top:1px solid var(--line);
  padding-top:18px;
}

.story-nav a {
  display:block;
  text-decoration:none;
  padding:10px 0;
  font-size:11px;
  text-transform:uppercase;
  font-weight:800;
  letter-spacing:.08em;
  color:var(--muted);
}

.story-block {
  padding:36px 0;
  border-top:1px solid var(--line);
}

.story-block h3 {
  font-size:36px;
  line-height:1;
  margin:0 0 14px;
  text-transform:uppercase;
}

.story-block p {
  max-width:760px;
  line-height:1.65;
  color:#605a54;
}

.image-block {
  min-height:460px;
  border-radius:30px;
  background:var(--img) center/cover no-repeat;
  margin:22px 0;
}


/* ---------------------------------------------------------------------------
   FORM GRID
   --------------------------------------------------------------------------- */

.form-grid {
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:12px;
}

.full {
  grid-column:1/-1;
}


/* ---------------------------------------------------------------------------
   SCROLL REVEAL — disabled in v2.1, see additions layer
   --------------------------------------------------------------------------- */

.reveal {
  opacity:1;
  transform:none;
  transition:none;
}

.reveal.on {
  opacity:1;
  transform:none;
}


/* ---------------------------------------------------------------------------
   RESPONSIVE
   --------------------------------------------------------------------------- */

@media(max-width:900px) {
  .nav {
    top:10px;
    height:auto;
    padding:14px;
    border-radius:22px;
  }

  .navlinks {
    display:none;
  }

  .menu {
    display:block;
  }

  .hero>.wrap, .section-head, .work-grid, .split, .contactbox, .story {
    grid-template-columns:1fr;
  }

  .mini {
    grid-template-columns:1fr;
  }

  .capabilities, .process {
    grid-template-columns:1fr 1fr;
  }

  .service-grid {
    grid-template-columns:1fr;
  }

  .story-nav {
    position:relative;
    top:auto;
    display:grid;
    grid-template-columns:1fr 1fr;
  }
}

@media(max-width:560px) {
  .wrap {
    width:min(100% - 28px,1120px);
  }

  .hero {
    padding-top:110px;
  }

  h1 {
    font-size:58px;
  }

  .hero p {
    font-size:17px;
  }

  .section {
    padding:76px 0;
  }

  .section-title {
    font-size:46px;
  }

  .capabilities, .process, .form-grid {
    grid-template-columns:1fr;
  }

  .work-card {
    min-height:390px;
  }

  .work-card h3 {
    font-size:36px;
  }

  .footer .wrap {
    display:grid;
  }

  .story-nav {
    grid-template-columns:1fr;
  }
}

/* =============================================================================
   ADDITIONS LAYER
   -----------------------------------------------------------------------------
   Everything above this line is the approved v2.1 design, unchanged.
   Everything below is additive and individually justified. Each block cites the
   audit section that called for it. Nothing here alters an approved value on a
   desktop browser; the opt-in blocks do nothing at all until switched on.
   ============================================================================= */

/* A1 — iOS viewport units (audit §06)
   94vh includes browser chrome on iOS, so the hero overflowed and pushed the
   CTA below the fold. svh is the visible viewport. Desktop is unaffected. */
@supports (height: 100svh) {
  .hero {
    min-height: 94svh;
  }
  .hero > .wrap {
    min-height: calc(94svh - 190px);
  }
}

/* A2 — keyboard focus (audit §06)
   The approved design has no focus styling at all, which makes keyboard
   navigation invisible on the dark ground. Mouse users never see this. */
:focus-visible {
  outline: 2px solid var(--orange2);
  outline-offset: 3px;
  border-radius: 2px;
}
.light :focus-visible,
.service :focus-visible {
  outline-color: var(--orange);
}

/* A3 — reduced motion (audit §05, §06)
   The 28s marquee runs regardless of the OS setting. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .orange-band div {
    animation: none;
    transform: none;
  }
  .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* A4 — scroll reveal, opt-in (audit §05, risk R7, decision D5)
   v2.1 deliberately disabled reveal to fix an iOS *local-file* preview bug that
   does not occur over HTTP. The original v2.0 behaviour is restored only when
   the theme option is on, which adds .has-reveal to <body>. Content is visible
   in the base cascade, so a JS failure can never hide it. */
body.has-reveal .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s ease, transform .7s ease;
}
body.has-reveal .reveal.on {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  body.has-reveal .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* A5 — WCAG AA contrast (audit §12, decision D3 — APPROVED, now default)
   Four measured failures in the approved palette: kicker orange 3.83 on paper
   and 4.31 on charcoal, white-on-orange buttons 4.24, section lead 3.34.
   Brand fills and display type are untouched; only small text and button
   grounds move. Switched on by the theme option, which is on by default.

   Two grounds matter on the light side, not one: --paper (#f6f3ee) and the
   Approach section's --paper2 (#ece7df). #a94818 is the lightest orange that
   clears 4.5 on both, and on white inside .service. */
html[data-contrast="aa"] {
  --orange-type-light: #a94818;  /* 5.23 paper / 4.70 paper2 / 5.79 white */
  --orange-type-dark:  #e27a36;  /* 6.15 on --charcoal                    */
  --orange-cta:        #b8511f;  /* 4.96 white-on-fill                    */
}

/* A17.5 — 2026-08-26. `--muted: #726c65` used to sit in the block above, applied
   globally. It was measured against --paper only, and on dark grounds it runs
   the wrong way:

     value      on Soft White   on Charcoal   on Obsidian
     #726c65        4.75            3.55          3.82
     SLATE          3.33            5.07          5.45

   Applied everywhere, it was fixing light surfaces by breaking every dark one,
   including the footer. Now scoped to light grounds, so dark surfaces keep
   SLATE, which is both the Brand Book value and the more accessible one there.

   Accessibility wins where the two conflict. This is the case where they don't. */
html[data-contrast="aa"] .light,
html[data-contrast="aa"] .service,
html[data-contrast="aa"] .step {
  --muted: #726c65;              /* 4.75 on --paper. --paper2 now equals
                                    --paper (A16 note), so one figure covers
                                    both light grounds. */
}

/* Light grounds. .step b belongs here, not below — the Approach strip it sits
   in is a light section, so the dark-ground value would take it from 3.44 to
   2.41 and make the failure worse. */
html[data-contrast="aa"] .light .kicker,
html[data-contrast="aa"] .service .kicker,
html[data-contrast="aa"] .step b {
  color: var(--orange-type-light);
}

/* Dark grounds. */
html[data-contrast="aa"] .dark .kicker,
html[data-contrast="aa"] .hero .kicker,
html[data-contrast="aa"] .contact .kicker,
html[data-contrast="aa"] .mini-card b,
html[data-contrast="aa"] .cap b,
html[data-contrast="aa"] .work-card small {
  color: var(--orange-type-dark);
}

html[data-contrast="aa"] .navlinks .cta,
html[data-contrast="aa"] .btn.primary,
html[data-contrast="aa"] .submit,
html[data-contrast="aa"] .orange-band {
  background: var(--orange-cta);
  border-color: var(--orange-cta);
}

/* A6 — real wordmark, opt-in (audit risk R2, decision D2)
   The approved nav fakes the wordmark in Georgia with a skewed <i> for the
   apostrophe, which brand book §16.1 forbids. When the theme option selects the
   real SVG, header.php emits .logo--mark instead. 140px wide renders 26.5px
   tall in the 58px pill, clearing the required X of 12.6px on all four sides —
   the existing nav geometry already satisfies the clear-space rule. */
.logo--mark {
  display: block;
  line-height: 0;
}
.logo--mark svg,
.logo--mark img {
  display: block;
  width: 140px;
  height: auto;
}
@media (max-width: 560px) {
  .logo--mark svg,
  .logo--mark img {
    width: 120px;  /* brand-book minimum for the full wordmark */
  }
}

/* A7 — WordPress admin bar
   The nav is position:fixed at top:16px and would sit under the admin bar. */
.admin-bar .nav {
  top: 48px;
}
.admin-bar .mobile {
  top: 118px;
}
@media screen and (min-width: 783px) {
  .admin-bar .nav {
    top: 48px;
  }
}
@media screen and (max-width: 900px) {
  .admin-bar .nav {
    top: 42px;
  }
  .admin-bar .mobile {
    top: 112px;
  }
}

/* A8 — accessibility utilities
   Skip link and screen-reader text, required by the semantic templates. */
.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.skip-link:focus {
  position: fixed;
  z-index: 100;
  top: 12px;
  left: 12px;
  clip: auto;
  width: auto;
  height: auto;
  margin: 0;
  padding: 12px 18px;
  border-radius: 999px;
  background: var(--orange);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
}

/* A9 — form states
   The approved forms are visual placeholders with no validation affordances. */
.field-error {
  display: block;
  margin-top: 6px;
  color: var(--orange2);
  font-size: 12px;
  font-weight: 600;
}
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--orange2);
}
.form-notice {
  grid-column: 1 / -1;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid #2c2a28;
  background: #0a0a0a;
  color: #fff;
  font-size: 14px;
  line-height: 1.5;
}
.form-notice.is-error {
  border-color: var(--orange2);
}
.hp-field {
  position: absolute !important;
  left: -9999px;
}
.submit[disabled] {
  opacity: .6;
  cursor: progress;
}

/* A10 — editor content
   page.php renders post_content for prose pages (privacy policy, legal). */
.prose {
  max-width: 760px;
  line-height: 1.65;
  color: #605a54;
}
.prose h2,
.prose h3 {
  color: var(--ink);
  text-transform: uppercase;
}
.prose a {
  color: var(--orange);
}
.prose img,
.prose figure {
  max-width: 100%;
  height: auto;
  border-radius: 18px;
}
.alignwide,
.alignfull {
  max-width: 100%;
}
.aligncenter {
  margin-inline: auto;
}

/* A11 — brand-book display leading (audit risk R6 — APPROVED, now default)
   Now that Playfair Display actually loads, the conflict between the mockup
   and the governing system is visible rather than theoretical. The approved
   v2.1 values are 0.79 on h1 and 0.89 on section titles; brand book v9.7 §18.1
   floors display line-height at 92% and says "never tighter". This raises only
   the four rules that sit below that floor. Playfair's extenders are longer
   than the fallback face the mockup was drawn against, which is why leading
   that read as composed in Iowan reads as collision in Playfair.

   To keep the tighter hero for first impression while section titles breathe,
   drop the `h1` rule below — the other three carry the collision risk. */
html[data-leading="brandbook"] h1 {
  line-height: .92;
}
html[data-leading="brandbook"] .section-title {
  line-height: .92;
}
html[data-leading="brandbook"] .work-card h3 {
  line-height: .92;
}
html[data-leading="brandbook"] .mock h3 {
  line-height: .92;
}

/* A12 — sticky mobile CTA (decision D5)
   Below 900px the nav collapses into the drawer and the header CTA goes with
   it, leaving the primary action unreachable without scrolling back to the top.
   The bar is server-rendered and visible without JavaScript; app.js only ever
   hides it. Desktop is untouched — every rule here is inside the query. */
.sticky-cta {
  display: none;
}
@media screen and (max-width: 900px) {
  .sticky-cta {
    position: fixed;
    z-index: 60;
    right: 0;
    bottom: 0;
    left: 0;
    display: block;
    padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
    background: rgba(15, 15, 15, .94);
    border-top: 1px solid #2c2a28;
    transition: transform .3s ease, opacity .3s ease;
  }
  .sticky-cta .btn {
    display: block;
    width: 100%;
    text-align: center;
  }
  /* Moved rather than display:none so it animates out, and so the link is
     never focusable while it is off screen. */
  .sticky-cta.is-off {
    opacity: 0;
    transform: translateY(100%);
    pointer-events: none;
    visibility: hidden;
  }
  /* The bar floats over the page, so the foot of the document needs room to
     clear it. Paired with lagence_show_sticky_cta() — the class is only ever
     present on a request that actually renders the bar. */
  body.has-sticky-cta {
    padding-bottom: 84px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sticky-cta {
    transition: none;
  }
}

/* A13 — work-card hover (decision D5)
   The approved card is inert under the cursor: nothing but the pointer shape
   signals that the whole tile is a link. Touch devices are excluded through
   (hover: hover) so no card is left stuck in a hover state after a tap, and the
   whole block is skipped under reduced motion rather than merely shortened.
   :focus-visible is carried alongside :hover so the keyboard sees it too. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .work-card {
    transition: transform .45s ease, border-color .45s ease;
  }
  .work-card.image:before {
    transition: transform .6s ease;
  }
  .work-card .arrow {
    transition: transform .45s ease, background-color .45s ease, border-color .45s ease;
  }
  .work-card:hover,
  .work-card:focus-visible {
    transform: translateY(-6px);
    border-color: var(--orange);
  }
  .work-card.image:hover:before,
  .work-card.image:focus-visible:before {
    transform: scale(1.05);
  }
  .work-card:hover .arrow,
  .work-card:focus-visible .arrow {
    transform: translate(4px, -4px);
    background: var(--orange);
    border-color: var(--orange);
  }
}

/* A14 — Fluent Forms, restyled to the approved system
   -----------------------------------------------------------------------------
   The inquiry form is a Fluent Forms form. Fluent Forms' own stylesheet is
   switched off in inc/fluentform.php through its supported filter, so nothing
   here is fighting specificity — these are the only rules the form has.

   The approved v2.1 sheet already styles `input, select, textarea` globally, so
   the controls inherit the right ground, border, radius and padding with no
   help. What follows is the layout Fluent Forms wraps them in, the states the
   static mockup never had, and the submit button. */

/* Fluent Forms marks required fields with an asterisk in the label. The
   approved design is placeholder-driven and has no visible labels at all, so
   the label row is removed rather than hidden with visibility. */
.lagence-form .ff-el-input--label {
  display: none;
}
.lagence-form .ff-el-group {
  margin: 0 0 12px;
}
/* Asserted rather than inherited. Fluent Forms' skin styles this class, and a
   class beats the approved sheet's `input, select, textarea` rule — so these
   values are restated here and the form stays correct even if the dequeue in
   inc/fluentform.php stops matching after an update. Values are the approved
   ones, unchanged. */
.lagence-form.lagence-form .ff-el-form-control {
  display: block;
  width: 100%;
  max-width: 100%;
  background: #0a0a0a;
  border: 1px solid #2c2a28;
  border-radius: 14px;
  color: #fff;
  padding: 15px 16px;
  font: inherit;
  line-height: normal;
}
.lagence-form.lagence-form .ff-el-form-control:focus {
  outline: 2px solid var(--orange2);
  outline-offset: 3px;
}
.lagence-form.lagence-form .ff-el-form-control::placeholder {
  color: #8a837c;
  opacity: 1;
}
.lagence-form.lagence-form textarea.ff-el-form-control {
  min-height: 120px;
  resize: vertical;
}

/* The full form is the two-column grid from the approved contact box; the
   message and consent rows span it. Fluent Forms emits a flat list of groups,
   so the grid is declared on the form itself. */
.lagence-form--full .ff-el-group {
  margin: 0;
}
.lagence-form--full .frm-fluent-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.lagence-form--full .ff_full,
.lagence-form--full .ff-el-group:has(textarea),
.lagence-form--full .ff-el-group:has(input[type="checkbox"]),
.lagence-form--full .ff_submit_btn_wrapper {
  grid-column: 1 / -1;
}

/* Consent. Fluent Forms renders a checkbox as a list item with its own label,
   which is the one label in the form that must stay visible. */
/* Fluent Forms nests the checkbox inside its label, so the label is the flex
   container — putting the row on .ff-el-form-check would lay out a single child
   and leave the box and its text running together. Doubled class again: the
   structural sheet also matches these at (0,2,0) and loads after ours. */
.lagence-form.lagence-form .ff-el-form-check-label {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13px;
  line-height: 1.45;
  color: #c4beb7;
}
.lagence-form.lagence-form .ff-el-form-check-input {
  width: auto;
  margin: 3px 0 0;
  flex: 0 0 auto;
}

/* Submit. Matches .submit in the approved sheet exactly; Fluent Forms carries
   its own button classes and inline colour, both overridden here. */
.lagence-form .ff-btn-submit,
.lagence-form .ff-btn.ff-btn-submit {
  width: 100%;
  border: 0;
  background: var(--orange);
  color: #fff;
  border-radius: 999px;
  padding: 15px 20px;
  font: inherit;
  font-weight: 900;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
}
html[data-contrast="aa"] .lagence-form .ff-btn-submit,
html[data-contrast="aa"] .lagence-form .ff-btn.ff-btn-submit {
  background: var(--orange-cta);
}
.lagence-form .ff-btn-submit:disabled,
.lagence-form.ff-form-loading .ff-btn-submit {
  opacity: .6;
  cursor: progress;
}

/* Error state. Fluent Forms adds .ff-el-is-error to the group and prints the
   message in .error; both are branded to match .field-error from A9. */
.lagence-form .ff-el-is-error .ff-el-form-control,
.lagence-form .ff-el-form-control.ff-el-is-error {
  border-color: var(--orange2);
}
.lagence-form .error,
.lagence-form .text-danger,
.lagence-form .ff-el-is-error-message {
  display: block;
  margin-top: 6px;
  color: var(--orange2);
  font-size: 12px;
  font-weight: 600;
}

/* Success and failure notices, styled as .form-notice from A9. */
.lagence-form .ff-message-success,
.lagence-form .ff-errors-in-stack,
.ff-message-success {
  grid-column: 1 / -1;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid #2c2a28;
  background: #0a0a0a;
  color: #fff;
  font-size: 14px;
  line-height: 1.5;
}
.lagence-form .ff-errors-in-stack {
  border-color: var(--orange2);
}
.lagence-form .ff-message-success p:last-child,
.ff-message-success p:last-child {
  margin-bottom: 0;
}

/* Mobile. The contact box already collapses; the form grid has to follow it,
   and the submit stops being full-bleed on the short front-page variant. */
@media (max-width: 900px) {
  .lagence-form--full .frm-fluent-form {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 560px) {
  .lagence-form .ff-el-group {
    margin-bottom: 10px;
  }
  .lagence-form .ff-btn-submit {
    padding: 16px 20px;   /* a comfortable tap target on a phone */
  }
}

/* Fluent Forms ships a honeypot as an off-screen text input; the approved sheet
   already hides .hp-field, and this is its Fluent Forms equivalent. */
.lagence-form .ff_hidden,
.lagence-form input[name="__ff_hp"] {
  position: absolute !important;
  left: -9999px;
}

/* A15 — mobile corrections and the client strip
   ============================================================================= */

/* A15.1 — contact box on a phone
   The approved box carries 36px of padding and a 50px gap, drawn for a 1120px
   grid. On a 390px screen that padding alone eats 72px of the 390 available and
   the gap opens a void between the heading and the first field. Desktop is
   untouched; only the phone breakpoint changes. */
@media (max-width: 900px) {
  .contactbox {
    gap: 26px;
  }
}
@media (max-width: 560px) {
  .contactbox {
    padding: 22px 18px;
    gap: 20px;
    border-radius: 24px;
  }
}

/* A15.2 — header scrim
   The nav is a floating pill inset from the page edges, so whatever is behind
   it shows in the strip around it. Over the dark sections that is invisible;
   over a light section the top of the screen reads as a beige band with
   headline text sliding under it. A gradient scrim gives the pill a consistent
   dark ground to sit on without turning it into a full-width bar, which would
   lose the floating treatment the approved design is built on.

   Painted from the nav's own stacking context, so no markup changes. */
.nav::before {
  content: "";
  position: fixed;
  z-index: -1;
  top: 0;
  right: 0;
  left: 0;
  height: 96px;
  pointer-events: none;
  background: linear-gradient(180deg, var(--black) 0%, rgba(15, 15, 15, .88) 48%, rgba(15, 15, 15, 0) 100%);
}
.admin-bar .nav::before {
  height: 128px;
}

/* A15.3 — sticky mobile CTA, corrected
   Three faults in A12. The link inherited no vertical padding, so the label sat
   in a 0-height box and read as small and off-centre; it had no explicit type
   size; and the bar was present from the first paint, overlapping the header
   CTA it duplicates.

   It now appears only once the header CTA has scrolled away and hides again on
   return, which is the behaviour asked for. That makes it JavaScript-gated
   rather than progressively enhanced — a deliberate trade, since a bar that
   cannot know the scroll position cannot honour the rule. The header CTA and
   the inline forms remain reachable without script. */
@media screen and (max-width: 900px) {
  .sticky-cta {
    opacity: 0;
    visibility: hidden;
    transform: translateY(110%);
    pointer-events: none;
  }
  .sticky-cta.is-on {
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
  }
  .sticky-cta .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 52px;      /* a comfortable target, and the label is centred in it */
    padding: 14px 20px;
    font-size: 13px;
    line-height: 1;
    text-align: center;
  }
}

/* A15.4 — client strip
   A compact dark band. Names are set in the nav's uppercase tracked treatment
   rather than as headings, because they are evidence, not hierarchy. */
.clients {
  padding: 54px 0;
}
.client-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 38px;
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
}
.client-grid li {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--line);   /* PLATINUM. was #cfc9c2, off-book. */
}
[dir="rtl"] .client-grid li {
  letter-spacing: normal;
  text-transform: none;
}
@media (max-width: 560px) {
  .clients {
    padding: 40px 0;
  }
  .client-grid {
    gap: 12px 24px;
  }
  .client-grid li {
    font-size: 13px;
  }
}

/* =============================================================================
   A16 — 2026-08-26. Single post, Work index, client logo wall, counter strip.
   All colour via Brand Book tokens only. No new hex values.
   ============================================================================= */

/* A16.1 — single post */
.post-hero {
  margin: 34px 0 0;
}
.post-hero img {
  display: block;
  width: 100%;
  height: auto;
}
.post-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 18px;
  margin-top: 64px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.post-nav a {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
}
.post-nav a:hover {
  color: var(--orange);
}
[dir="rtl"] .post-nav a {
  letter-spacing: normal;
  text-transform: none;
}

/* A16.2 — Work filter chips.
   Platinum at rest, signal only on the active chip. Signal stays well under
   the 5% ceiling because exactly one chip is ever active. */
.work-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 30px 0 44px;
  padding: 0;
  list-style: none;
}
.work-filters a {
  display: inline-block;
  padding: 9px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  transition: color .2s ease, border-color .2s ease, background-color .2s ease;
}
.work-filters a:hover {
  color: var(--ink);
  border-color: var(--ink);
}
.work-filters a.is-on {
  color: var(--paper);
  background: var(--orange);
  border-color: var(--orange);
}
[dir="rtl"] .work-filters a {
  letter-spacing: normal;
  text-transform: none;
}

/* A16.3 — intentionally empty.
   The Work grid and card already exist in the frozen sheet above (see also
   A13 work-card hover). Do not redefine .work-grid / .work-card here. */

/* A16.4 — client logo wall.
   Platinum-toned at rest so the wall reads as one neutral field, full colour
   on hover. Keeps the neutrals carrying the page, per Brand Book 02.1. */
.logo-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1px;
  margin: 30px 0 0;
  padding: 0;
  list-style: none;
  background: var(--edge);
  border: 1px solid var(--edge);
}
.logo-wall li {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 116px;
  padding: 22px;
  background: var(--charcoal);
}
.logo-wall img {
  max-width: 100%;
  max-height: 46px;
  width: auto;
  height: auto;
  filter: grayscale(1) brightness(0) invert(76%) sepia(6%) saturate(240%) hue-rotate(3deg);
  opacity: .8;
  transition: filter .3s ease, opacity .3s ease;
}
.logo-wall li:hover img {
  filter: none;
  opacity: 1;
}
.logo-wall__name {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--line);
  text-align: center;
}
[dir="rtl"] .logo-wall__name {
  letter-spacing: normal;
  text-transform: none;
}
@media (max-width: 560px) {
  .logo-wall {
    grid-template-columns: repeat(2, 1fr);
  }
  .logo-wall li {
    min-height: 92px;
    padding: 16px;
  }
}

/* A16.5 — counter strip */.counters {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin: 40px 0 0;
  padding: 0;
  list-style: none;
}
.counters li {
  text-align: center;
}
.counters__n {
  display: block;
  font-size: clamp(38px, 6vw, 72px);
  line-height: 1;
  letter-spacing: -.02em;
}
.counters__label {
  display: block;
  margin-top: 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
[dir="rtl"] .counters__label {
  letter-spacing: normal;
  text-transform: none;
}
@media (max-width: 560px) {
  .counters {
    grid-template-columns: 1fr;
    gap: 26px;
  }
}

/* =============================================================================
   A17 — 2026-08-26. Mobile overlap bugs found in device screenshots.
   ============================================================================= */

/* A17.1 — header scrim, removed.
   A15.2 painted a 96px dark gradient behind the floating pill so text sliding
   under it would not show through. Over a dark section it is invisible. Over a
   light one the fade from opaque black to transparent renders as a grey smear
   halfway down the screen, and on the Approach strip it swallowed the "02 /
   DEFINE" row outright.

   The scrim was solving for the pill being only 80% opaque. Making the pill
   opaque solves the same problem without painting anything outside it, and
   restores the floating treatment the approved design is built on: on a light
   section you now see the light section around the pill, which is correct.

   Its old colour was also rgba(15,15,15,...) — the pre-Brand-Book black. */
.nav::before {
  display: none;
}
.nav {
  background: rgba(10, 10, 10, .96);   /* OBSIDIAN. was rgba(16,16,16,.80) */
}

/* A17.2 — sticky CTA, missing off state.
   app.js toggles `.is-off` on the bar whenever a form or the contact section is
   on screen, so the floating CTA does not sit on top of the real one. No rule
   for `.is-off` was ever written, so the class did nothing and the bar covered
   the contact headline and the Send Request button.

   Declared after `.is-on` and doubled up so it wins on equal specificity
   regardless of which class the script sets last. */
.sticky-cta.is-off,
.sticky-cta.is-on.is-off {
  opacity: 0;
  visibility: hidden;
  transform: translateY(110%);
  pointer-events: none;
}

/* A17.3 — footer clearance.
   The bar is fixed to the bottom, so the last rows of the footer sat behind it
   at the end of the scroll. */
@media screen and (max-width: 900px) {
  .footer {
    padding-bottom: 96px;
  }
}

/* A17.4 — page canvas, dark.
   `body` was `var(--paper)`. Every section paints its own ground (.light,
   .dark, .contact, .hero, .footer all set background explicitly), so the body
   colour was only ever visible in one place: the rubber-band overscroll strip
   iOS Safari exposes above the first section and below the last. That strip
   rendered beige on a brand that is dark by default, so pulling the page at
   either end flashed a light band around a dark site.

   Set on `html` as well as `body`, because Safari takes the overscroll colour
   from the root element, not from body. */


