/* ==========================================================================
   Dice Codes — Design System
   Prototype stylesheet. In production this compiles to one file, inlined
   above the fold and deferred below it.
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */

:root {
  /* Monochrome. Black, white and grey only. Hierarchy is carried by
     contrast, weight and space rather than by hue. */
  --ink:        #0E0E10;   /* page ground */
  --ink-raise:  #141416;
  --panel:      #1A1A1D;   /* cards */
  --panel-2:    #232327;   /* card hover */
  --line:       #2C2C31;   /* hairlines */
  --grid:       rgba(255, 255, 255, 0.034);   /* graph paper */
  --grid-size:  52px;

  --accent:       #FFFFFF;              /* the only accent is pure white */
  --accent-dim:   #B8B8BC;
  --accent-ghost: rgba(255, 255, 255, 0.08);

  --bone:       #F2F2F0;   /* primary text */
  --mute:       #9B9BA0;   /* secondary text */
  --faint:      #8C8C93;   /* labels, meta, breadcrumbs.
                              4.69:1 on the darkest card, so it clears AA
                              on the page ground and on every panel */

  --display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --body:    "Chivo", "Segoe UI", system-ui, sans-serif;

  /* Perfect fourth scale, fluid */
  --t-xs:   0.78rem;
  --t-sm:   0.92rem;
  --t-base: 1.0625rem;
  --t-md:   clamp(1.25rem, 1.05rem + 0.6vw, 1.5rem);
  --t-lg:   clamp(1.6rem, 1.25rem + 1.4vw, 2.35rem);
  --t-xl:   clamp(2.1rem, 1.4rem + 2.9vw, 3.9rem);
  --t-2xl:  clamp(2.6rem, 1.2rem + 5.2vw, 5rem);
  --t-huge: clamp(4rem, 0.5rem + 14vw, 14rem);

  --gutter: clamp(1.25rem, 4vw, 5.5rem);
  --rail:   3.25rem;              /* left gutter rail width */
  --max:    82rem;

  --step: clamp(4.5rem, 9vw, 9.5rem);   /* vertical section rhythm */

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --- Reset -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--ink);
  color: var(--bone);
  font-family: var(--body);
  font-size: var(--t-base);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;

  /* Graph paper. This is a studio that measures things, and the page prints
     its own readings in the hero, so it belongs on ruled ground. Kept at
     roughly 3% white: legible as a texture at arm's length, invisible as a
     pattern. Two gradients rather than an image, so it costs no request. */
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  background-position: center top;
}

img, svg, canvas { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.15em; max-width: 68ch; }

::selection { background: var(--accent); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --- Glass -------------------------------------------------------------- */
/* Two tiers, and the split is deliberate.

   .glass       Real backdrop-filter. Applied only where page content
                actually passes behind the element: the header, the mobile
                menu overlay, the floating contact button. backdrop-filter
                makes the compositor re-sample everything underneath on
                every frame, so it is rationed rather than sprayed around.

   .glass-flat  The same surface treatment with no filter, for panels
                sitting on a flat ground where there is nothing behind to
                blur. On a solid background the two are indistinguishable,
                and this one costs nothing.

   Both use a top-to-bottom fill plus an inset highlight on the top edge,
   which is what reads as a lit pane of glass rather than a grey box. */

.glass,
.glass-flat {
  background-image: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.075),
    rgba(255, 255, 255, 0.028)
  );
  background-color: rgba(255, 255, 255, 0.012);
  border: 1px solid rgba(255, 255, 255, 0.10);
  /* Inset highlight only. A large drop shadow is what sells a floating pane,
     but on a flat ground it is invisible and still costs a full blur pass per
     element per frame. With twenty of these on a page that was enough to stall
     compositing, so the expensive shadow is reserved for .glass below. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

/* Real blur is reserved for chrome that is transient or short: the header
   strip, the mobile overlay, the services panel. The floating contact
   button is fixed and on screen the whole time, so blurring behind it would
   force a full-viewport re-sample every frame on top of the WebGL canvas.
   It uses the flat surface with a solid ground instead. */
.float-btn {
  background-color: rgba(28, 28, 32, 0.92);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 8px 22px rgba(0, 0, 0, 0.40);
}

.glass {
  -webkit-backdrop-filter: blur(18px) saturate(165%);
  backdrop-filter: blur(18px) saturate(165%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 12px 34px rgba(0, 0, 0, 0.34);
}

/* Hover lifts the pane rather than recolouring it */
.glass-hover { transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease); }
.glass-hover:hover {
  background-color: rgba(255, 255, 255, 0.055);
  border-color: rgba(255, 255, 255, 0.20);
}

/* Safari and Firefox without backdrop-filter fall back to an opaque panel,
   so chrome elements never turn illegible against scrolling content. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background-color: rgba(20, 20, 23, 0.95); }
}

/* --- Layout primitives -------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Blocks are rendered straight into <main> by the block editor, with no
   wrapper of their own. That makes main the page container: it constrains and
   pads every block, and supplies the vertical rhythm that a .section used to.
   Blocks that carry their own .wrap, or are meant to run edge to edge, opt
   back out. Without this every block sits at viewport width with no gutter,
   which is what "the design is broken" looks like. */

#main > * {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

#main > .hero,
#main > .marquee {
  max-width: none;
  padding-inline: 0;
}

/* Rhythm. Each block is a section, so the gap between them is the section
   step. A section head owns the gap to whatever it introduces, so the pair
   stays together rather than drifting apart. */

#main > * + * { margin-block-start: var(--step); }
#main > .head + * { margin-block-start: 0; }
#main > .marquee { margin-block: calc(var(--step) * 0.75); }
#main > .hero + * { margin-block-start: var(--step); }
/* The service links sit where the gauge used to, so they belong to the hero
   rather than reading as a section of their own. */
#main > .hero + .pills { margin-block-start: calc(var(--step) * 0.4); }

/* A run of prose under a head reads as one passage, not as separate sections. */
#main > p + p,
#main > p + figure,
#main > figure + p { margin-block-start: 1.1rem; }

.section { padding-block: var(--step); position: relative; }
.section--tight { padding-block: calc(var(--step) * 0.6); }
.section--flush-top { padding-top: 0; }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--ink);
  padding: 0.75rem 1.25rem;
  font-family: var(--display);
  font-weight: 700;
  z-index: 999;
}
.skip:focus { left: 1rem; top: 1rem; }

/* --- The brace: this brand's structural device -------------------------- */
/* Used instead of tracked all-caps eyebrows. Lowercase, braces in grey.   */

.brace {
  font-family: var(--display);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--mute);
  letter-spacing: 0.01em;
  display: inline-flex;
  gap: 0.45em;
  margin-bottom: 1.4rem;
}
.brace::before { content: "{"; color: var(--faint); }
.brace::after  { content: "}"; color: var(--faint); }

/* Section head: heading left, supporting prose right */

.head {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 4vw, 5rem);
  align-items: end;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.head h2 { font-size: var(--t-xl); }
.head p  { color: var(--mute); margin: 0; font-size: var(--t-md); line-height: 1.5; }

@media (max-width: 780px) {
  .head { grid-template-columns: 1fr; align-items: start; gap: 1.25rem; }
}

/* --- Buttons ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-sm);
  letter-spacing: 0.005em;
  padding: 0.95em 1.7em;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease),
              border-color 0.2s var(--ease);
}

.btn--fill {
  background: var(--accent);
  color: var(--ink);
}
.btn--fill:hover { background: var(--bone); }

.btn--line {
  color: var(--bone);
}
.btn--line:hover { border-color: var(--accent); color: var(--accent); }

/* Outline button sitting on an inverted (white) surface */
.btn--on-light {
  border-color: rgba(14, 14, 16, 0.28);
  color: var(--ink);
}
.btn--on-light:hover { border-color: var(--ink); color: var(--ink); }

/* --- Header ------------------------------------------------------------- */

.hdr {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  padding: 1.15rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  transition: background-color 0.3s var(--ease), backdrop-filter 0.3s var(--ease);
}
/* The header only becomes glass once content is passing behind it. Over the
   hero it stays fully transparent, so the dice are not blurred at rest. */
.hdr[data-stuck="true"] {
  background-image: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
  background-color: rgba(14, 14, 16, 0.62);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hdr[data-stuck="true"] { background-color: rgba(14, 14, 16, 0.96); }
}

.logo {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.32rem;
  letter-spacing: -0.045em;
  color: var(--bone);
  white-space: nowrap;
}
.logo b { font-weight: 700; color: var(--faint); }

.nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 2.2rem);
  font-size: var(--t-sm);
}
.nav > a,
.nav-trigger {
  position: relative;
  color: var(--mute);
  transition: color 0.18s var(--ease);
  padding-block: 0.35rem;
}
.nav > a:hover,
.nav > a[aria-current="page"],
.nav-trigger:hover,
.nav-trigger[aria-expanded="true"] { color: var(--bone); }

/* A hairline that grows from the centre on hover. Cheap, and it gives the
   nav a state that is visible without relying on colour alone. */
.nav > a::after,
.nav-trigger::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transition: transform 0.25s var(--ease);
}
.nav > a:hover::after,
.nav > a[aria-current="page"]::after,
.nav-trigger:hover::after,
.nav-trigger[aria-expanded="true"]::after { transform: scaleX(1); }

/* --- Services mega menu -------------------------------------------------- */

.nav-item { position: relative; display: flex; align-items: center; }

/* Contact block belongs to the mobile overlay only */
.nav-foot { display: none; }

.nav-trigger {
  font: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
}
.nav-trigger i {
  width: 0.34em;
  height: 0.34em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-0.09em, -0.09em);
  transition: transform 0.25s var(--ease);
}
.nav-trigger[aria-expanded="true"] i { transform: rotate(225deg) translate(-0.02em, -0.02em); }

.mega {
  position: absolute;
  top: calc(100% + 1.35rem);
  left: 50%;
  width: min(40rem, 88vw);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.15rem;
  padding: 0.6rem;
  border-radius: 1.35rem;
  z-index: 70;
  transform: translateX(-50%) translateY(-0.5rem);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
.mega[hidden] { display: none; }
.nav-item[data-open="true"] .mega {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

/* Bridges the gap between trigger and panel so the pointer can travel
   between them without the menu closing underneath it */
.mega::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -1.4rem;
  height: 1.4rem;
}

.mega a {
  display: block;
  padding: 0.85rem 1rem;
  border-radius: 0.9rem;
  transition: background-color 0.18s var(--ease);
}
.mega a:hover { background: rgba(255, 255, 255, 0.06); }
.mega b {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-sm);
  color: var(--bone);
  margin-bottom: 0.2rem;
}
.mega span { font-size: var(--t-xs); color: var(--faint); line-height: 1.5; }

/* The nav overlay is a child of the header, so the logo and the close button
   need to sit above it inside the header's own stacking context */
.hdr .logo,
.hdr-actions { position: relative; z-index: 60; }

.hdr-actions { display: flex; align-items: center; gap: 0.65rem; }

.icon-btn {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--bone);
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.icon-btn svg { width: 1.05rem; height: 1.05rem; fill: currentColor; }

/* --- Mobile menu -------------------------------------------------------- */

.menu-toggle {
  display: none;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: none;
  color: var(--bone);
  cursor: pointer;
}
.menu-toggle span {
  display: block;
  width: 1.05rem;
  height: 1px;
  background: currentColor;
  position: relative;
  transition: background-color 0.2s var(--ease);
}
.menu-toggle span::before,
.menu-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition: transform 0.25s var(--ease);
}
.menu-toggle span::before { top: -5px; }
.menu-toggle span::after  { top: 5px; }

body[data-menu="open"] .menu-toggle span { background: transparent; }
body[data-menu="open"] .menu-toggle span::before { transform: translateY(5px) rotate(45deg); }
body[data-menu="open"] .menu-toggle span::after  { transform: translateY(-5px) rotate(-45deg); }

@media (max-width: 900px) {
  .menu-toggle { display: grid; }

  .nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: 5.75rem var(--gutter) 2.5rem;
    background-color: rgba(14, 14, 16, 0.86);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    backdrop-filter: blur(28px) saturate(180%);
    z-index: 50;
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform 0.35s var(--ease), visibility 0s linear 0.35s;
    overflow-y: auto;
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .nav { background-color: rgba(14, 14, 16, 0.98); }
  }

  /* Each row is a full-width tap target with a hairline under it, which is
     easier to hit than centred text and reads as a list rather than a pile */
  .nav > a,
  .nav-trigger {
    padding-block: 1rem;
    border-bottom: 1px solid var(--line);
    width: 100%;
  }
  .nav > a::after,
  .nav-trigger::after { display: none; }
  .nav-item { display: block; width: 100%; }
  .nav-trigger { justify-content: space-between; }

  /* The mega panel becomes an inline expandable list */
  .mega {
    position: static;
    width: auto;
    transform: none;
    opacity: 1;
    pointer-events: auto;
    grid-template-columns: 1fr;
    gap: 0;
    padding: 0.35rem 0 0.85rem;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    box-shadow: none;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .mega::before { display: none; }
  .mega a { padding: 0.6rem 0 0.6rem 1rem; border-left: 1px solid var(--line); border-radius: 0; }
  .mega a:hover { background: none; }
  .mega b { font-size: var(--t-base); }

  /* Contact block pinned under the list */
  .nav-foot {
    margin-top: auto;
    padding-top: 2rem;
    display: grid;
    gap: 0.5rem;
  }
  .nav-foot a { font-size: var(--t-sm); color: var(--mute); }
  .nav-foot .btn { justify-content: center; margin-bottom: 0.75rem; }

  .nav > a,
  .nav-trigger {
    font-family: var(--display);
    font-weight: 700;
    font-size: var(--t-md);
    color: var(--bone);
  }
  body[data-menu="open"] .nav {
    transform: none;
    visibility: visible;
    transition: transform 0.35s var(--ease), visibility 0s;
  }
  body[data-menu="open"] { overflow: hidden; }

  /* The header CTA duplicates the menu on small screens */
  .hdr-actions .btn { display: none; }
}

/* --- Left rail: rotated contact, scroll progress ------------------------ */

.rail {
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--rail);
  z-index: 40;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.rail a {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  color: var(--faint);
  pointer-events: auto;
  transition: color 0.2s var(--ease);
}
.rail a:hover { color: var(--accent); }

.progress {
  position: fixed;
  right: 1.4rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 7rem;
  background: var(--line);
  z-index: 40;
}
.progress span {
  position: absolute;
  inset: 0 0 auto 0;
  height: 0%;
  background: var(--accent);
  display: block;
}

@media (max-width: 900px) {
  .rail, .progress { display: none; }
}

/* --- Hero --------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: 6rem 2.5rem;
  isolation: isolate;
}

/* Hero background layers, back to front:
   -5 fallback wash · -4 dice canvas · -3 cursor light · -2 scrim · -1 grain
   Content sits at auto, above all of them. */

#dice-canvas {
  position: absolute;
  inset: 0;
  z-index: -4;
  width: 100%;
  height: 100%;
}

/* Static composition shown when WebGL is off or motion is reduced */
.hero-fallback {
  position: absolute;
  inset: 0;
  z-index: -5;
  background:
    radial-gradient(52rem 34rem at 76% 28%, rgba(255,255,255,0.045), transparent 68%),
    radial-gradient(38rem 30rem at 12% 82%, rgba(255,255,255,0.025), transparent 70%);
}

/* Cursor light. Sits under the scrim, so it lifts the dice on the right
   without ever washing out the headline on the left. The custom properties
   default to a fixed position, which is what touch devices get. */
.hero-light {
  position: absolute;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  background: radial-gradient(
    28rem 28rem at var(--mx, 72%) var(--my, 38%),
    rgba(255, 255, 255, 0.11),
    rgba(255, 255, 255, 0.04) 42%,
    transparent 70%);
}

/* Grain. Pure black renders as dead space on a large screen; a fine noise
   gives it material. Desaturated, so the palette stays monochrome. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 140px 140px;
}

/* Scrim: keeps headline contrast steady wherever the dice happen to drift.
   Wide screens shade left to right, because the copy sits in the left
   column. Narrow screens shade top to bottom, because it does not. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background: linear-gradient(100deg,
    var(--ink) 0%,
    rgba(14, 14, 16, 0.92) 34%,
    rgba(14, 14, 16, 0.55) 56%,
    transparent 78%);
}

@media (max-width: 900px) {
  .hero::before {
    background: linear-gradient(180deg,
      rgba(14, 14, 16, 0.97) 0%,
      rgba(14, 14, 16, 0.96) 55%,
      rgba(14, 14, 16, 0.72) 82%,
      rgba(14, 14, 16, 0.35) 100%);
  }
}

.hero-inner { position: relative; width: 100%; }

.hero h1 {
  font-size: var(--t-2xl);
  max-width: 18ch;
  margin-bottom: 1.1rem;
}
/* The emphasised phrase is drawn as outlined type rather than coloured.
   It borrows the marquee's treatment, so the page has one idea, not two. */
.hero h1 em {
  font-style: normal;
  color: var(--bone);
}
@supports (-webkit-text-stroke: 1px black) {
  .hero h1 em {
    color: transparent;
    -webkit-text-stroke: 1.5px var(--bone);
  }
}

/* --- Rotating service line ---------------------------------------------- */
/* The headline names one discipline at a time, because the agency does eight
   and a sentence that lists all eight is not a headline. Every word is in the
   markup: a crawler reads the full list, a screen reader gets one sentence,
   and the animation only decides which word is on screen. */

.h1-rotate { display: grid; gap: 0.08em; }

/* Wider than a normal hero headline, and deliberately so. .hero h1 caps at
   18ch, which the longest service name overruns by about a word. The rotating
   variant has to fit its widest member, not its average one. */
.hero h1.h1-rotate { max-width: 23ch; }
.h1-lead, .h1-tail { display: block; }

.rotator {
  display: grid;
  grid-template-areas: "word";
  justify-items: start;
}

/* Base state shows the first word only, so a headline still reads as a whole
   sentence if the script never runs. .has-js takes over from there. */
.rotator-word {
  grid-area: word;
  font-style: normal;
  color: var(--bone);
  opacity: 0;
  white-space: nowrap;
}
.rotator-word:first-child { opacity: 1; }

@supports (-webkit-text-stroke: 1px black) {
  .rotator-word { color: transparent; -webkit-text-stroke: 1.5px var(--bone); }
}

.has-js .rotator-word {
  opacity: 0;
  transform: translateY(0.26em);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
}
.has-js .rotator-word.is-on { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .has-js .rotator-word { transition: none; transform: none; }
}

/* The longest service name is about 12 times the headline's font size wide,
   while the available column is roughly 0.92 of the viewport. Solving the two
   against the headline's clamp puts the crossover near 800px, so nowrap stops
   at 900 rather than at a phone breakpoint. Below this the words wrap, which
   costs a line and never overflows. */
@media (max-width: 900px) {
  .rotator-word { white-space: normal; }
  .hero h1.h1-rotate { max-width: none; }
}

.hero-sub {
  color: var(--mute);
  font-size: var(--t-md);
  max-width: 60ch;
  line-height: 1.55;
  margin-bottom: 1.85rem;
}

.hero-cta { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-bottom: 2.1rem; }

/* --- The gauge: this page, measured ------------------------------------- */
/* Replaces the three claims that used to sit here. In a monochrome system
   there is no green to mean "passing", so each reading carries a meter bar
   showing the value against its budget instead. That is more informative
   than a colour anyway: it shows how much headroom is left, not just
   pass or fail. */

.gauge { border-radius: 1.1rem; overflow: hidden; max-width: 54rem; }

.gauge-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.85rem 1.15rem;
  border-bottom: 1px solid var(--line);
}
.gauge-head .brace { margin-bottom: 0; font-size: var(--t-xs); }
.gauge-when {
  font-family: var(--display);
  font-size: var(--t-xs);
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.gauge-grid { display: grid; grid-template-columns: repeat(4, 1fr); }

.gauge-cell {
  padding: 1.05rem 1.15rem 1rem;
  border-right: 1px solid var(--line);
}
.gauge-cell:last-child { border-right: 0; }

.g-val {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 1rem + 1.5vw, 2.1rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--bone);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.55rem;
}
.g-lbl { display: block; font-size: var(--t-xs); color: var(--mute); line-height: 1.35; }

/* Meter: filled portion is the reading, the track is the budget */
.g-meter {
  display: block;
  height: 2px;
  background: var(--line);
  margin: 0.85rem 0 0.5rem;
  overflow: hidden;
}
.g-meter i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--bone);
  transition: width 1s var(--ease);
}
/* Over budget: the bar fills completely and turns into a hatch, so it is
   distinguishable without relying on colour or on seeing both states */
.gauge-cell[data-over="true"] .g-meter i {
  background: repeating-linear-gradient(
    -45deg, var(--mute) 0 3px, transparent 3px 6px);
}
.gauge-cell[data-over="true"] .g-val { color: var(--mute); }

.g-bud { display: block; font-size: var(--t-xs); color: var(--faint); font-variant-numeric: tabular-nums; }

.gauge-foot {
  margin: 0;
  padding: 0.85rem 1.15rem;
  border-top: 1px solid var(--line);
  font-size: var(--t-xs);
  color: var(--faint);
  max-width: none;
}

/* Two by two below tablet rather than a single tall column */
@media (max-width: 820px) {
  .gauge-grid { grid-template-columns: repeat(2, 1fr); }
  .gauge-cell:nth-child(2) { border-right: 0; }
  .gauge-cell:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
}

@media (prefers-reduced-motion: reduce) {
  .g-meter i { transition: none; }
}

/* --- Service grid: staggered, not a uniform 3-up ------------------------ */

.svc-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 1.8vw, 1.6rem);
  align-items: start;
}
/* The offset is the point: columns 2 and 3 drop, breaking the grid line */
.svc-grid > :nth-child(3n+2) { margin-top: clamp(1.5rem, 4vw, 4rem); }
.svc-grid > :nth-child(3n+3) { margin-top: clamp(3rem, 8vw, 8rem); }

.svc {
  display: block;
  border-radius: 1.25rem;
  padding: clamp(1.5rem, 2.4vw, 2.1rem);
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}
.svc:hover { border-color: rgba(255, 255, 255, 0.22); }

.svc-glyph {
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--faint);
  line-height: 1;
  margin-bottom: 2.4rem;
  display: block;
}

.svc h3 { font-size: var(--t-md); margin-bottom: 0.7rem; }
.svc p  { color: var(--mute); font-size: var(--t-sm); margin: 0 0 1.2rem; line-height: 1.6; }

.svc-more {
  font-family: var(--display);
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--faint);
  transition: color 0.2s var(--ease);
}
.svc:hover .svc-more { color: var(--bone); }

@media (max-width: 900px) {
  .svc-grid { grid-template-columns: repeat(2, 1fr); }
  .svc-grid > :nth-child(3n+2),
  .svc-grid > :nth-child(3n+3) { margin-top: 0; }
  .svc-grid > :nth-child(even) { margin-top: 2rem; }
}
@media (max-width: 600px) {
  .svc-grid { grid-template-columns: 1fr; }
  .svc-grid > * { margin-top: 0 !important; }
}

/* --- Marquee band ------------------------------------------------------- */

.marquee {
  overflow: hidden;
  border-block: 1px solid var(--line);
  padding-block: clamp(1rem, 2vw, 2rem);
  user-select: none;
}
.marquee-track {
  display: flex;
  align-items: center;
  gap: 0.28em;
  width: max-content;
  animation: slide 42s linear infinite;
}
/* A slash separates the words, so the band reads as a list rather than
   one run-on string. Set a step quieter than the words themselves. */
.marquee-track b {
  flex: none;
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-huge);
  line-height: 0.95;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--faint);
  opacity: 0.5;
}
.marquee-track b::before { content: "/"; }
.marquee span {
  font-family: var(--display);
  font-size: var(--t-huge);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.045em;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--mute);
  white-space: nowrap;
}
/* Alternate words fill instead of outlining, so the band has a rhythm
   rather than reading as one long outlined string. The fill is a dark
   grey, not white, so it stays a background element. */
.marquee span:nth-of-type(even) {
  color: var(--panel-2);
  -webkit-text-stroke-width: 0;
}
@keyframes slide { to { transform: translateX(-50%); } }

/* --- Work / case study cards -------------------------------------------- */

.work-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 2vw, 2rem);
}
.work {
  position: relative;
  display: block;
  border-radius: 1.25rem;
  overflow: hidden;
}
.work:hover { border-color: rgba(255, 255, 255, 0.22); }

.work-shot {
  aspect-ratio: 16 / 10;
  background: linear-gradient(148deg, var(--panel-2), var(--ink-raise));
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
}
.work-shot::after {
  content: attr(data-note);
  font-family: var(--display);
  font-size: var(--t-xs);
  color: var(--faint);
  letter-spacing: 0.06em;
}
.work-body { padding: clamp(1.3rem, 2.2vw, 1.9rem); }
.work-meta {
  display: flex;
  gap: 0.5rem;
  font-size: var(--t-xs);
  color: var(--faint);
  margin-bottom: 0.7rem;
  font-family: var(--display);
}
.work h3 { font-size: var(--t-md); margin-bottom: 0.9rem; }
.work-result {
  font-family: var(--display);
  font-weight: 700;
  color: var(--bone);
  font-size: var(--t-sm);
}

@media (max-width: 700px) { .work-grid { grid-template-columns: 1fr; } }

/* --- Process: dice faces as step markers -------------------------------- */
/* Six steps, six faces of a die. The sequence is real, so the marker is    */
/* allowed to be a counter — and it is the brand's own object.             */

/* An <ol>, because six numbered stages genuinely are a sequence. The list
   markers are suppressed since the dice faces carry the numbering visually. */
.process {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 3.5vw, 3.25rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
.step { position: relative; padding-top: 1.75rem; border-top: 1px solid var(--line); }
.step h3 { font-size: var(--t-md); margin: 1.15rem 0 0.5rem; }
.step p  { color: var(--mute); font-size: var(--t-sm); margin: 0; }

.die {
  width: 2.9rem;
  height: 2.9rem;
  border-radius: 0.6rem;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  gap: 0.22rem;
  padding: 0.5rem;
}
.die i {
  width: 0.32rem;
  height: 0.32rem;
  border-radius: 50%;
  background: var(--mute);
  align-self: center;
  justify-self: center;
}
/* Pip placement per face */
.die[data-face="1"] i:nth-child(1) { grid-area: 2 / 2; }
.die[data-face="2"] i:nth-child(1) { grid-area: 1 / 1; }
.die[data-face="2"] i:nth-child(2) { grid-area: 3 / 3; }
.die[data-face="3"] i:nth-child(1) { grid-area: 1 / 1; }
.die[data-face="3"] i:nth-child(2) { grid-area: 2 / 2; }
.die[data-face="3"] i:nth-child(3) { grid-area: 3 / 3; }
.die[data-face="4"] i:nth-child(1) { grid-area: 1 / 1; }
.die[data-face="4"] i:nth-child(2) { grid-area: 1 / 3; }
.die[data-face="4"] i:nth-child(3) { grid-area: 3 / 1; }
.die[data-face="4"] i:nth-child(4) { grid-area: 3 / 3; }
.die[data-face="5"] i:nth-child(1) { grid-area: 1 / 1; }
.die[data-face="5"] i:nth-child(2) { grid-area: 1 / 3; }
.die[data-face="5"] i:nth-child(3) { grid-area: 2 / 2; }
.die[data-face="5"] i:nth-child(4) { grid-area: 3 / 1; }
.die[data-face="5"] i:nth-child(5) { grid-area: 3 / 3; }
.die[data-face="6"] i:nth-child(1) { grid-area: 1 / 1; }
.die[data-face="6"] i:nth-child(2) { grid-area: 1 / 3; }
.die[data-face="6"] i:nth-child(3) { grid-area: 2 / 1; }
.die[data-face="6"] i:nth-child(4) { grid-area: 2 / 3; }
.die[data-face="6"] i:nth-child(5) { grid-area: 3 / 1; }
.die[data-face="6"] i:nth-child(6) { grid-area: 3 / 3; }

@media (max-width: 880px) { .process { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .process { grid-template-columns: 1fr; } }

/* --- Statement block ---------------------------------------------------- */

/* Only the lead sentence gets the display treatment. The paragraphs that
   follow stay at reading size, or the whole block becomes a wall. */
.statement .lead {
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--t-md);
  line-height: 1.36;
  letter-spacing: -0.015em;
  color: var(--bone);
  max-width: 40ch;
  margin-bottom: 1.5rem;
}
.statement p { color: var(--mute); max-width: 56ch; }
.statement .btn { margin-top: 0.75rem; }

/* --- Testimonials ------------------------------------------------------- */

.quotes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2vw, 1.75rem);
}
.quote {
  border-radius: 1.25rem;
  padding: clamp(1.5rem, 2.4vw, 2.1rem);
}
.quote--wide { max-width: 44rem; }
.quote blockquote { margin: 0 0 1.5rem; font-size: var(--t-sm); line-height: 1.7; color: var(--bone); }
.quote figcaption { font-size: var(--t-xs); color: var(--faint); }
.quote figcaption b { display: block; color: var(--bone); font-family: var(--display); font-size: var(--t-sm); margin-bottom: 0.15rem; }
.stars { color: var(--mute); font-size: var(--t-sm); letter-spacing: 0.15em; margin-bottom: 1rem; }

@media (max-width: 880px) { .quotes { grid-template-columns: 1fr; } }

/* --- FAQ ---------------------------------------------------------------- */

.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 1.5rem 3rem 1.5rem 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-md);
  position: relative;
  transition: color 0.2s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  color: var(--faint);
  font-size: 1.5rem;
  font-weight: 400;
}
.faq details[open] summary::after { content: "\2013"; }
.faq details p { color: var(--mute); font-size: var(--t-sm); padding-bottom: 1.6rem; margin: 0; }

/* --- CTA band ----------------------------------------------------------- */

.cta-band {
  background: var(--accent);
  color: var(--ink);
  border-radius: 1.75rem;
  padding: clamp(2.5rem, 6vw, 5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}
.cta-band h2 { font-size: var(--t-xl); color: var(--ink); max-width: 15ch; }
.cta-band p  { color: rgba(14, 14, 16, 0.72); margin: 1rem 0 0; font-size: var(--t-sm); }
.cta-band .btn--fill { background: var(--ink); color: var(--accent); }
.cta-band .btn--fill:hover { background: #000; }
.cta-actions { display: flex; flex-direction: column; gap: 0.75rem; align-items: start; }
.cta-actions a { width: fit-content; }

@media (max-width: 780px) { .cta-band { grid-template-columns: 1fr; } }

/* --- Footer ------------------------------------------------------------- */

.ftr { border-top: 1px solid var(--line); padding-block: var(--step) 2.5rem; }
.ftr-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  margin-bottom: 4rem;
}
.ftr h4 {
  font-size: var(--t-xs);
  color: var(--faint);
  font-weight: 500;
  letter-spacing: 0.02em;
  margin-bottom: 1.2rem;
}
.ftr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.65rem; }
.ftr li a { font-size: var(--t-sm); color: var(--mute); transition: color 0.18s var(--ease); }
.ftr li a:hover { color: var(--accent); }
.ftr-blurb { color: var(--mute); font-size: var(--t-sm); max-width: 34ch; margin: 1.2rem 0 0; }

.ftr-base {
  border-top: 1px solid var(--line);
  padding-top: 2rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  font-size: var(--t-xs);
  color: var(--faint);
}
.ftr-base a { color: var(--faint); }
.ftr-base a:hover { color: var(--accent); }

@media (max-width: 880px) { .ftr-grid { grid-template-columns: 1fr 1fr; } }

/* --- Floating contact --------------------------------------------------- */

.float {
  position: fixed;
  right: 1.4rem;
  bottom: 1.4rem;
  z-index: 55;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.float a {
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  color: var(--bone);
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}
.float a:hover { background-color: var(--accent); color: var(--ink); border-color: var(--accent); }
.float svg { width: 1.15rem; height: 1.15rem; fill: currentColor; }

/* --- Breadcrumbs -------------------------------------------------------- */

.crumbs {
  font-size: var(--t-xs);
  color: var(--faint);
  padding-top: 7.5rem;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.crumbs a:hover { color: var(--accent); }
.crumbs span[aria-current] { color: var(--mute); }

/* --- Inner page hero ---------------------------------------------------- */

.page-hero { padding-block: 3rem var(--step); }
.page-hero h1 { font-size: var(--t-xl); max-width: 18ch; margin-bottom: 1.5rem; }
.page-hero .hero-sub { max-width: 56ch; }
.page-hero .hero-cta { margin-top: 2.5rem; margin-bottom: 0; }

/* A brace label placed below the block it annotates rather than above */
.brace--note { margin-top: 1.5rem; margin-bottom: 0; }

/* Answer-first paragraph. Leads with the direct answer so AI engines and
   featured snippets can lift it cleanly. */
.answer {
  border-left: 2px solid var(--line);
  padding-left: clamp(1rem, 2vw, 1.75rem);
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--bone);
  max-width: 60ch;
}
.answer p:last-child { margin-bottom: 0; }

/* --- Two column prose --------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(1.75rem, 5vw, 5rem);
  align-items: start;
}
.split h2 { font-size: var(--t-lg); position: sticky; top: 6.5rem; }
.split > div > p { color: var(--mute); }
.split > div > p strong { color: var(--bone); font-weight: 700; }
@media (max-width: 820px) {
  .split { grid-template-columns: 1fr; }
  .split h2 { position: static; }
}

/* --- Feature list ------------------------------------------------------- */

/* No 01/02/03 markers here. These are components of a service, not a
   sequence, and the dice pips on the process section are the counter this
   brand already owns. A brace marks each item instead. */
.features { display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.feature { background: var(--ink); padding: 1.75rem 0 1.75rem 2.25rem; position: relative; }
.feature h3 { font-size: var(--t-md); margin-bottom: 0.5rem; }
.feature h3::before {
  content: "{";
  position: absolute;
  left: 0;
  color: var(--faint);
  font-weight: 500;
}
.feature p { color: var(--mute); font-size: var(--t-sm); margin: 0; }

/* --- Pill link grid (niche landing pages) ------------------------------- */

.pills { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.pill {
  border-radius: 999px;
  padding: 0.6em 1.15em;
  font-size: var(--t-sm);
  color: var(--mute);
  transition: color 0.2s var(--ease);
}
.pill:hover { color: var(--bone); }

/* --- Stat row ----------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 3vw, 2.5rem);
  border-block: 1px solid var(--line);
  padding-block: clamp(2rem, 4vw, 3.25rem);
}
.stat strong {
  display: block;
  font-family: var(--display);
  font-size: var(--t-lg);
  font-weight: 700;
  letter-spacing: -0.035em;
  color: var(--accent);
  line-height: 1.05;
  margin-bottom: 0.6rem;
}
.stat span { font-size: var(--t-sm); color: var(--mute); }
@media (max-width: 700px) { .stats { grid-template-columns: repeat(2, 1fr); } }

/* --- Table -------------------------------------------------------------- */

.table-scroll { overflow-x: auto; }
table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
  min-width: 34rem;
}
th, td { text-align: left; padding: 1rem 1.25rem 1rem 0; border-bottom: 1px solid var(--line); }
th { font-family: var(--display); color: var(--bone); font-weight: 700; }
td { color: var(--mute); }
td strong { color: var(--bone); font-weight: 700; }

/* --- Placeholder marker ------------------------------------------------- */
/* Anything the client must replace before launch is visibly flagged.      */

.todo {
  background: rgba(255, 255, 255, 0.10);
  color: var(--bone);
  border: 1px dashed var(--mute);
  border-radius: 0.35rem;
  padding: 0.05em 0.45em;
  font-family: var(--display);
  font-size: 0.85em;
}

/* --- Reveal on scroll --------------------------------------------------- */
/* One orchestrated reveal per section, not an effect on every element.    */

/* Scoped to .has-js, which main.js sets on <html> before first paint. If the
   script fails to load or throws, the class is never set and every section
   stays visible. Hiding content by default and relying on JS to bring it back
   means one broken script is a blank page. */

.has-js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.has-js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .has-js [data-reveal] { opacity: 1; transform: none; }
  .marquee-track { animation: none; }
}

/* ==========================================================================
   WordPress
   Classes that only exist once this is a theme rather than a prototype:
   post content, pagination, forms, and the accessibility helpers core
   expects to be present.
   ========================================================================== */

/* --- Screen reader text -------------------------------------------------- */
/* Core and several plugins output this class and assume the theme styles it.
   Without it, labels intended only for screen readers appear on the page. */

.screen-reader-text {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
}
.screen-reader-text:focus {
  clip-path: none;
  height: auto;
  width: auto;
  margin: 0;
  padding: 0.75rem 1.25rem;
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 1000;
  background: var(--accent);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 700;
}

/* --- Long-form post content ---------------------------------------------- */

.prose { max-width: 42rem; }
.prose > * { margin-bottom: 1.25em; }
.prose h2 { font-size: var(--t-lg); margin-top: 2.5em; margin-bottom: 0.6em; }
.prose h3 { font-size: var(--t-md); margin-top: 2em; margin-bottom: 0.5em; }
.prose p, .prose li { color: var(--mute); }
.prose strong { color: var(--bone); }
.prose a { color: var(--bone); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { text-decoration-thickness: 2px; }
.prose ul, .prose ol { padding-left: 1.25rem; }
.prose li { margin-bottom: 0.5em; }
.prose img { border-radius: 0.75rem; }
.prose blockquote {
  margin: 2em 0;
  padding-left: 1.5rem;
  border-left: 2px solid var(--line);
  font-family: var(--display);
  font-size: var(--t-md);
  color: var(--bone);
}
.prose code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9em;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0.3rem;
  padding: 0.1em 0.35em;
}
.prose pre {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  padding: 1.25rem;
  overflow-x: auto;
}
.prose pre code { background: none; border: 0; padding: 0; }

.post-hero-img { border-radius: 1.25rem; margin-bottom: 1rem; }

.post-meta {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-size: var(--t-sm);
  color: var(--faint);
  margin-top: 1.25rem;
}

/* --- Pagination ---------------------------------------------------------- */

.pagination { margin-top: 3.5rem; }
.pagination .nav-links { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pagination .page-numbers {
  display: inline-grid;
  place-items: center;
  min-width: 2.6rem;
  height: 2.6rem;
  padding-inline: 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-family: var(--display);
  font-size: var(--t-sm);
  color: var(--mute);
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.pagination .page-numbers:hover { border-color: var(--accent); color: var(--bone); }
.pagination .page-numbers.current {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
}
.page-links { margin-top: 2rem; display: flex; gap: 0.5rem; align-items: center; }

/* --- Search form --------------------------------------------------------- */

.search-wrap { max-width: 28rem; margin-top: 2rem; }
.search-form { display: flex; gap: 0.5rem; }
.search-field {
  flex: 1;
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--bone);
  font-family: var(--body);
  font-size: var(--t-base);
  padding: 0.8rem 1.25rem;
}
.search-field::placeholder { color: var(--faint); }
.search-field:focus {
  outline: none;
  border-color: var(--accent);
}
.search-form .btn { flex: none; }

/* --- Alignment ----------------------------------------------------------- */

.alignwide { max-width: 1440px; margin-inline: auto; }
.alignfull { max-width: none; margin-inline: calc(50% - 50vw); width: 100vw; }
.aligncenter { margin-inline: auto; }
.alignleft { float: left; margin: 0 1.5rem 1rem 0; }
.alignright { float: right; margin: 0 0 1rem 1.5rem; }

/* --- Grid toggle --------------------------------------------------------- */
/* Set from the Customizer. Turning it off removes the background entirely
   rather than setting the colour to transparent, so nothing is painted. */

body.no-grid { background-image: none; }

/* --- Logo ---------------------------------------------------------------- */

.logo-img {
  width: var(--logo-w, 168px);
  height: auto;
  display: block;
}

/* --- Comments ------------------------------------------------------------ */

.comment-list { list-style: none; margin: 0; padding: 0; }
.comment-list li { border-top: 1px solid var(--line); padding-block: 1.5rem; }
.comment-list .children { list-style: none; padding-left: 1.5rem; }
.comment-form input:not([type="submit"]),
.comment-form textarea {
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  color: var(--bone);
  font-family: var(--body);
  padding: 0.8rem 1rem;
  margin-bottom: 1rem;
}
.comment-form label { display: block; font-size: var(--t-sm); color: var(--mute); margin-bottom: 0.35rem; }
