/* ==========================================================================
   URLS LLC — Understanding Real Life Solutions
   --------------------------------------------------------------------------
   1. Tokens          6. About            11. Footer
   2. Base            7. Appearances      12. Motion
   3. Layout & type   8. Case studies     13. Placeholder system
   4. Header & nav    9. Reviews          14. Design review toolbar
   5. Hero / Work    10. Contact
   ========================================================================== */

/* 1. TOKENS ---------------------------------------------------------------
   The six editable theme tokens (--bg, --surface, --text, --text2, --brand,
   --cta) are set on :root by js/theme-boot.js. Defaults below = Flyer Blue.
   Everything else derives from them, so one change updates the whole site. */
:root {
  --bg: #0b0c0f;
  --surface: #16181e;
  --text: #f6f7f9;
  --text2: #a6adba;
  --brand: #2f7dff;
  --cta: #1a5cff;
  --brand-ink: #ffffff;
  --cta-ink: #ffffff;
  --paper: var(--text); /* lighter of --bg / --text (set by JS) */
  --overhang-ink: var(--brand); /* About overlay past the photo edge (set by JS) */
  --accent-text: var(--cta); /* CTA colour when readable as text on --bg, else brand (set by JS) */

  --line: color-mix(in srgb, var(--text) 14%, transparent);
  --line-strong: color-mix(in srgb, var(--text) 28%, transparent);
  --brand-soft: color-mix(in srgb, var(--brand) 16%, transparent);
  --ghost: color-mix(in srgb, var(--text) 11%, transparent);

  --font-display: "Rubik", "Arial Black", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-script: "Yellowtail", "Brush Script MT", cursive;

  --gutter: clamp(1rem, 4vw, 3rem);
  --maxw: 1240px;
  --radius: 4px;
  /* Spacing follows the window's height as well as its width, so wide but
     short screens (laptops) tighten up; text sizes are never affected. On
     a window about 1000px or taller these resolve to their full values. */
  --section-pad: clamp(5rem, min(11vw, 15vh), 9.5rem);
  /* One clear space everywhere: big divider word <-> content above and below it */
  --divider-size: calc(clamp(5rem, 19vw, 16rem) * var(--mark-scale, 1));
  --divider-gap: clamp(2.75rem, min(4.5vw, 5.6vh), 3.5rem);
  /* ...and section headline (with its script tagline or intro) <-> what follows */
  --head-gap: clamp(2rem, min(3.5vw, 4.8vh), 3rem);

  /* Set by JS: heights of the sticky review bar and header */
  --review-h: 0px;
  --header-h: 72px;

  /* Background pattern (default fence; js/theme-boot.js swaps it).
     Its shape is used as a mask, so the colour comes from the element. */
  --pattern: url("../assets/patterns/fence.svg");
  /* Fine grain */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.4 -.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* Worn-ink speckle mask: mostly solid with sparse breaks */
  --worn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -26 21.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3C/svg%3E");
}

/* 2. BASE ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scrollbar-gutter: stable; /* no sideways shift when scrolling is frozen */
  -webkit-text-size-adjust: 100%;
  font-synthesis: none;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--review-h) + var(--header-h) + 8px);
}

html.is-scroll-locked { overflow: hidden; }

/* Loading screen (shown only with JS; removed by js/site.js) */
.page-loader { display: none; }
.js .page-loader {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding-inline: var(--gutter);
  background: var(--bg);
  transition: opacity .6s ease, visibility 0s linear .6s;
}
.page-loader.is-done { opacity: 0; visibility: hidden; }
html.is-loading { overflow: hidden; }
.page-loader__title {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 135;
  font-weight: 850;
  font-size: calc(clamp(1.6rem, 6vw, 3.6rem) * var(--display-scale, 1));
  line-height: .98;
  letter-spacing: -.005em;
  word-spacing: var(--display-word-spacing, normal);
  text-transform: uppercase;
  color: var(--text);
  opacity: 0;                      /* appears once the fonts are ready */
  transition: opacity .5s ease;
}
.page-loader.has-fonts .page-loader__title { opacity: 1; }
.page-loader__script {
  margin: .03em 0 .065em; /* a little more room below than above, as in the hero */
  font-family: var(--font-script);
  font-weight: 400;
  font-variation-settings: normal;
  text-transform: none;
  font-size: calc(1.355em * var(--script-scale, 1)); /* 1.178em, then 15% bigger */
  line-height: 1;
  color: var(--accent-text);
}

/* With a photo configured, never flash the silhouette placeholder */
.has-photo-heroPortrait [data-portrait="heroPortrait"] .portrait__silhouette,
.has-photo-heroPortrait [data-portrait="heroPortrait"] .portrait__caption,
.has-photo-aboutPortrait [data-portrait="aboutPortrait"] .portrait__silhouette,
.has-photo-aboutPortrait [data-portrait="aboutPortrait"] .portrait__caption { visibility: hidden; } /* offer cards: page frozen while they drop */

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  overflow-x: clip;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* Restrained grain across the page */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 90;
  background-image: var(--grain);
  opacity: .07;
  mix-blend-mode: overlay;
}

img, svg { display: block; max-width: 100%; }
[hidden] { display: none !important; }
a { color: inherit; }
p, h1, h2, h3, dl, dd, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--brand); color: var(--brand-ink); }

:focus-visible {
  outline: 3px solid var(--accent-text);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 200;
  padding: .75rem 1rem;
  background: var(--cta);
  color: var(--cta-ink);
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 1rem; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* 3. LAYOUT & TYPE -------------------------------------------------------- */
.container {
  width: 100%;
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: var(--section-pad);
  overflow-x: clip; /* oversized type may cross vertically, never sideways */
}
.section > .container { position: relative; z-index: 2; }

.eyebrow {
  margin-bottom: 1.25rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text2);
}

.section-title {
  color: var(--brand);
  font-family: var(--font-display);
  font-variation-settings: "wdth" 112;
  font-weight: 800;
  font-size: calc(clamp(2.1rem, 4.6vw, 3.9rem) * var(--display-scale, 1));
  line-height: 1.02;
  letter-spacing: -.015em;
  max-width: 17ch;
  text-wrap: balance;
}

.section-head { margin-bottom: var(--head-gap); }
.section-head--split {
  display: grid;
  gap: var(--head-gap) 4rem;
  align-items: end;
}
@media (min-width: 900px) {
  .section-head--split { grid-template-columns: 1.3fr 1fr; }
}

.section-intro {
  margin-top: var(--head-gap);
  max-width: 54ch;
  color: var(--text2);
  font-size: 1.125rem;
}
.section-head--split .section-intro { margin-top: 0; }

.prose p + p { margin-top: 1.1em; }
.prose { max-width: 62ch; }

.fine-print {
  margin-top: var(--stack-gap, 1.25rem);
  font-size: .6885rem; /* ~11px: small print, one line where it fits */
  letter-spacing: .01em;
  color: var(--text2);
}

/* Buttons — label colour (--cta-ink) is auto-picked for contrast */
.btn {
  --_bg: transparent;
  --_fg: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-height: 3.25rem;
  padding: .85rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--radius);
  background: var(--_bg);
  color: var(--_fg);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: transform .2s ease, background-color .2s ease, border-color .2s ease, color .2s ease;
}
.btn--cta { --_bg: var(--cta); --_fg: var(--cta-ink); }
.btn--cta:hover { background: color-mix(in srgb, var(--cta) 86%, var(--cta-ink)); }
.btn--cta:focus-visible { outline-color: var(--text); }
.btn--ghost { border-color: var(--line-strong); }
.btn--ghost:hover { border-color: var(--text); }
.btn--sm { min-height: 2.6rem; padding: .55rem 1.1rem; font-size: .9375rem; }

/* Inline call-to-action link in body copy: the CTA colour, with a thin
   underline so it reads as a link without relying on colour alone */
.text-cta {
  color: var(--cta);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
}
.text-cta:hover { text-decoration-thickness: 2px; }

/* Rubik (upper & lowercase): show the headline words as typed, not forced to capitals */
html[data-font-display] :is(.hero__title, .hero__name, .page-loader__title) { text-transform: none; }
/* Faces with one set weight (the trial title fonts in js/theme-boot.js):
   every headline and moving word uses it, upright or italic as chosen */
html[data-display-weight] :is(.page-loader__title, .section-title, .cross-type, .brand__mark, .conveyor__track,
  .hero__name, .hero__title-line, .offer__num, .offer__title, .chapter__title, .appearance__logo-name,
  .appearance__title, .case__title, .review__mark) {
  font-weight: var(--display-weight) !important;
  font-style: var(--display-style, normal);
  font-variation-settings: normal;
}
html[data-display-weight] .cross-type { text-transform: uppercase; }
html[data-display-weight] .page-loader__script { font-style: normal; }
/* Trial title faces may carry their own letter spacing (js/theme-boot.js) */
html[data-display-tracking] :is(.page-loader__line, .section-title, .hero__name, .hero__title-line, .offer__title,
  .chapter__title, .appearance__title, .case__title, .brand__mark) { letter-spacing: var(--display-tracking); }
/* Script faces carry their own letter spacing (js/theme-boot.js) */
:is(.page-loader__script, .hero__script, .hero__title-script, .about__overlay, .about__script, .contact__script, .contact__social-title) {
  letter-spacing: var(--script-tracking, normal);
}
html[data-font-conveyor="rubik-dirt"] .cross-type { text-transform: uppercase; }
/* ...but the moving rows and big section dividers stay all caps */
html[data-font-conveyor="rubik"] .cross-type { text-transform: uppercase; font-weight: 800; }

/* Headline type follows the title font's word spacing (tighter for monospaced faces) */
.section-title, .hero__title-line, .offer__title, .case__title,
.appearance__title, .site-footer__mark, .cross-type {
  word-spacing: var(--display-word-spacing, normal);
}

/* Sections hidden from the design review toolbar (or config), with their nav links */
html[data-hide-case-studies] #case-studies,
html[data-hide-case-studies] .site-nav li:has(> a[href="#case-studies"]),
html[data-hide-reviews] #reviews,
html[data-hide-reviews] .site-nav li:has(> a[href="#reviews"]) { display: none; }

/* Oversized, light display type that crosses section boundaries */
.cross-type {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  user-select: none;
  font-family: var(--font-conveyor, var(--font-display));
  font-variation-settings: "wdth" 130;
  font-weight: 200;
  line-height: .78;
  letter-spacing: -.02em;
  white-space: nowrap;
  color: var(--ghost);
}

/* Clear space around the dividers. Each divider word sits across the top edge
   of its section; --div-up / --div-down are how far its letters reach above
   and below that edge (in divider-size units, measured per display font).
   The section above stops --divider-gap short of the letters' top, and the
   section below starts --divider-gap under their bottom. */
:root { --div-up: .335; --div-down: .385; }
/* Keyed to the conveyor font: the moving type's own face (see "Mixed Rubik") */
html[data-font-conveyor="rubik-dirt"] {
  --div-up: .34; --div-down: .39;
  --divider-size: calc(clamp(5rem, 19vw, 16rem) * var(--mark-scale, 1) * .81); /* 10% smaller, twice, in this face */
}
.section:has(> .cross-type--moving) { padding-top: calc(var(--divider-size) * var(--div-down) + var(--divider-gap)); }
.section:not(.contact) { padding-bottom: calc(var(--divider-size) * var(--div-up) + var(--divider-gap)); }

/* Moving dividers: the word repeats and drifts slowly to the left */
.cross-type--moving { left: 0; right: auto; }
.cross-type__track { display: inline-flex; }
.cross-type__track span { padding-right: .35em; }
@media (prefers-reduced-motion: no-preference) {
  .cross-type__track { animation: conveyor 45s linear infinite; }
}

/* 4. HEADER & NAV ---------------------------------------------------------- */
.site-header {
  position: sticky;
  top: var(--review-h);
  z-index: 50;
  transition: background-color .3s ease, border-color .3s ease;
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled,
.site-header.is-open {
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom-color: var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding: .9rem var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  text-decoration: none;
}
.brand__mark {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 150;
  font-weight: 900;
  font-size: calc(1.45rem * var(--display-scale, 1));
  letter-spacing: .01em;
  line-height: 1;
}
.brand__rl { color: var(--brand); } /* the R and L in teal, as in the logo picture */
.brand__llc {
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--text2);
}

.site-nav ul {
  display: flex;
  align-items: center;
  gap: clamp(.9rem, 2vw, 1.9rem);
  list-style: none;
}
.site-nav a:not(.btn) {
  position: relative;
  padding-block: .4rem;
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--text2);
  transition: color .2s ease;
}
.site-nav a:not(.btn):hover { color: var(--text); }
/* Current section: the CTA colour */
.site-nav a[aria-current="true"] { color: var(--cta); }

.nav-toggle {
  display: none;
  align-items: center;
  gap: .6rem;
  min-height: 2.75rem;
  padding: .4rem .9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: transparent;
  font-weight: 600;
  font-size: .9375rem;
  cursor: pointer;
}
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 18px;
  height: 2px;
  background: currentColor;
  transition: transform .25s ease, opacity .2s ease;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after { top: 6px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 1023px) {
  .js .nav-toggle { display: inline-flex; }
  .js .site-nav {
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    display: none;
    padding: .5rem var(--gutter) 1.5rem;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    max-height: calc(100svh - var(--review-h) - var(--header-h));
    overflow-y: auto;
  }
  .js .site-nav.is-open { display: block; }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav li { border-bottom: 1px solid var(--line); }
  .site-nav a:not(.btn) { display: block; padding: 1rem 0; font-size: 1.0625rem; }
  .site-nav__cta { border-bottom: 0 !important; padding-top: 1.25rem; }
  .site-nav__cta .btn { width: 100%; min-height: 3.25rem; }
  .no-js .site-nav ul, html:not(.js) .site-nav ul { flex-direction: row; flex-wrap: wrap; }
}

/* 5. HERO -------------------------------------------------------------------
   Desktop: portrait stage (left ~56%) + quiet panel (right), with the
   oversized wordmark sharing the same grid row and sitting along the bottom
   of both halves, in front of the portrait. Mobile: stage → wordmark → panel. */
.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-top: calc(var(--header-h) * -1);
  overflow-x: clip;
}

.hero__stage {
  position: relative;
  grid-row: 1;
  min-height: clamp(440px, 118vw, 640px);
  overflow: hidden;
  isolation: isolate;
}

/* Panel-layout patterns (one large artwork) are anchored right and sized
   to the area instead of repeating; the corner fades still apply so the
   texture stays sparse and clear of the text. */
html[data-pattern-layout="panel"] .hero__texture,
html[data-pattern-layout="panel"] .contact__texture {
  --pattern-size: auto 37.8rem; /* one fixed size, so the fence matches in both places */
  opacity: var(--pattern-opacity, .11); /* adjustable in the review toolbar */
}
html[data-pattern-layout="panel"] .hero__texture { /* fades out from the top right */
  -webkit-mask: var(--pattern) right top / var(--pattern-size) var(--pattern-repeat, no-repeat), radial-gradient(circle at 100% 0%, #000 0%, transparent 60%);
  -webkit-mask-composite: source-in;
  mask: var(--pattern) right top / var(--pattern-size) var(--pattern-repeat, no-repeat), radial-gradient(circle at 100% 0%, #000 0%, transparent 60%);
  mask-composite: intersect;
}
/* The contact section's fence stays lighter than the hero's */
html[data-pattern-layout="panel"] .contact__texture { opacity: .14; }
html[data-pattern-layout="panel"] .contact__texture { /* same scale as the hero, repeated to full height, fading out toward the left */
  -webkit-mask: var(--pattern-contact, var(--pattern)) right top / var(--pattern-size) var(--pattern-repeat, repeat-y), linear-gradient(90deg, transparent 30%, #000 100%);
  -webkit-mask-composite: source-in;
  mask: var(--pattern-contact, var(--pattern)) right top / var(--pattern-size) var(--pattern-repeat, repeat-y), linear-gradient(90deg, transparent 30%, #000 100%);
  mask-composite: intersect;
}
/* Desktop hero: fence runs the full height of the panel (same scale,
   repeated) and fades out toward the left, reaching between half and two thirds of the way across */
@media (min-width: 1100px) {
  html[data-pattern-layout="panel"] .hero__texture {
    -webkit-mask: var(--pattern) right top / var(--pattern-size) var(--pattern-repeat, repeat-y), linear-gradient(90deg, transparent 26%, #000 100%);
    -webkit-mask-composite: source-in;
    mask: var(--pattern) right top / var(--pattern-size) var(--pattern-repeat, repeat-y), linear-gradient(90deg, transparent 26%, #000 100%);
    mask-composite: intersect;
  }
}
/* Cracked plaster: a texture rather than a single artwork, so it is sized
   to each area's height and tiled to fill it */
html[data-pattern="cracked"] .hero__texture,
html[data-pattern="cracked"] .contact__texture { --pattern-size: auto 100%; --pattern-repeat: repeat; }

/* Fence & birds, hero: artwork 25% taller, and the fade reaches 25% further down */
html[data-pattern="fence-birds"] .hero__texture {
  --pattern-size: auto 47.25rem;
  -webkit-mask: var(--pattern) right top / var(--pattern-size) no-repeat, radial-gradient(117% 87.5% at 100% 0%, #000 0%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask: var(--pattern) right top / var(--pattern-size) no-repeat, radial-gradient(117% 87.5% at 100% 0%, #000 0%, transparent 100%);
  mask-composite: intersect;
}
html[data-pattern-layout="panel"] .appearance__logo::before {
  -webkit-mask: var(--pattern) right center / cover no-repeat;
  mask: var(--pattern) right center / cover no-repeat;
}

/* With no pattern selected, hide the layers that draw it */
html[data-pattern="none"] .hero__texture,
html[data-pattern="none"] .contact__texture,
html[data-pattern="none"] .appearance__logo::before { display: none; }

/* The image panel; the portrait breaks above its top edge */
.hero__panel-img {
  position: absolute;
  inset: 30% 0 0 0;
  background: var(--brand);
  z-index: -2;
}
.hero__panel-img::after { /* worn-ink grain inside the colour block */
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  opacity: .18;
  mix-blend-mode: multiply;
}

/* Opposing conveyors behind the portrait, one word per row.
   Rows alternate direction; sizes follow the colour block via cqh units. */
.hero__conveyors {
  position: absolute;
  inset: 30% 0 0 0;
  z-index: -1;
  display: grid;
  grid-template-rows: repeat(var(--rows, 6), 1fr); /* --rows set by js/site.js */
  align-items: center;
  overflow: hidden;
  container-type: size;
  pointer-events: none;
  user-select: none;
}
/* Rows nearly touch: line-height ~ cap height, and glyphs may overhang
   the row box vertically (clipped sideways only). */
/* Front layer: same geometry, drawn above the portrait (z 1) */
.hero__conveyors--front { z-index: 2; }
.hero__conveyors:not(.hero__conveyors--front) .conveyor.is-front,
.hero__conveyors--front .conveyor:not(.is-front) { visibility: hidden; }

.conveyor {
  overflow-x: clip;
  overflow-y: visible;
  white-space: nowrap;
  transform: translateY(var(--row-shift, 0px)); /* even spacing, set by js/site.js */
}
.conveyor__track {
  display: inline-flex;
  font-family: var(--font-conveyor, var(--font-display));
  font-variation-settings: "wdth" 150;
  font-weight: 900;
  font-size: var(--conv-font, calc(120cqh / var(--rows, 6))); /* --conv-font: js/site.js */
  line-height: .78;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--brand-ink) 20%, transparent);
  will-change: transform;
}
.conveyor__track span { padding-right: .45em; } /* a word space between repeats */
@media (prefers-reduced-motion: no-preference) {
  .conveyor__track { animation: conveyor var(--speed, 40s) linear infinite; }
  .conveyor:nth-child(even) .conveyor__track { animation-direction: reverse; }
}
@keyframes conveyor { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Large cursive accent in the space above his head */
.hero__script {
  position: absolute;
  top: calc(var(--header-h) + .25rem);
  left: 0;
  right: 4%; /* centres the script at 48%, over his head */
  z-index: 2;
  text-align: center;
  font-family: var(--font-script);
  font-size: calc(clamp(3.25rem, 15vw, 6rem) * var(--script-scale, 1));
  line-height: 1;
  color: var(--accent-text);
  transform: rotate(-8deg);
  text-shadow: 0 .04em .25em color-mix(in srgb, var(--bg) 55%, transparent);
  pointer-events: none;
}


.portrait {
  position: relative;
  margin: 0;
}
.portrait__silhouette {
  width: 100%;
  height: 100%;
}
.portrait__silhouette path {
  fill: color-mix(in srgb, var(--bg) 88%, var(--brand));
  stroke: color-mix(in srgb, var(--text) 30%, transparent);
  stroke-width: 1.5;
  stroke-dasharray: 6 6;
  vector-effect: non-scaling-stroke;
}
.portrait__caption {
  position: absolute;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--text) 55%, transparent);
}
.portrait img { width: 100%; height: 100%; object-fit: contain; object-position: bottom center; }
.portrait.has-image .portrait__caption { display: none; }

/* The portrait is anchored at the head and scaled so only the top
   --portrait-keep (60%) of the photo shows; the stage crops the rest,
   including the arms at the sides. */
.portrait--hero {
  --portrait-keep: .6;
  position: absolute;
  top: 10%;
  left: 52%; /* nudged right so his head lines up under the "Real Life" script */
  height: calc(90% / var(--portrait-keep));
  aspect-ratio: 4 / 5;
  transform: translateX(-50%);
  z-index: 1;
}
.portrait--hero .portrait__caption {
  left: 50%;
  top: 62%;
  transform: translateX(-50%);
  white-space: nowrap;
}

.hero__panel {
  position: relative;
  grid-row: 2;
  background: var(--surface);
  overflow: hidden;
}
.hero__texture { /* sparse pattern in one corner, faded out */
  position: absolute;
  inset: 0;
  background: var(--text);
  opacity: .07;
  -webkit-mask: var(--pattern), radial-gradient(circle at 100% 0%, #000 0%, transparent 55%);
  -webkit-mask-composite: source-in;
  mask: var(--pattern), radial-gradient(circle at 100% 0%, #000 0%, transparent 55%);
  mask-composite: intersect;
  pointer-events: none;
}
.hero__copy {
  /* headline size, shared by the name; js/site.js sets --title-fit */
  --hero-title-size: calc(clamp(1.5rem, 6.6vw, 3.2rem) * var(--display-scale, 1) * var(--title-fit, 1));
  position: relative;
  padding: 2.5rem var(--gutter) 3.5rem;
}

/* Name: same face, size and treatment as the headline lines */
.hero__name {
  color: var(--brand);
  font-family: var(--font-display);
  font-variation-settings: "wdth" 135;
  font-weight: 850;
  font-size: var(--hero-title-size);
  line-height: .98;
  letter-spacing: -.005em;
  word-spacing: var(--display-word-spacing, normal);
  text-transform: uppercase;
  text-wrap: balance;
}
.hero__name abbr { text-decoration: none; } /* spelled out in its title and in About */

.hero__title {
  display: flex;
  flex-direction: column;
  margin: 1.75rem 0 1.5rem;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 135;
  font-weight: 850;
  font-size: var(--hero-title-size);
  line-height: .98;
  letter-spacing: -.005em;
  text-transform: uppercase;
}
.hero__title-script {
  text-align: left; /* lines up with "Understanding" and "Solutions" */
  white-space: nowrap;
  margin: var(--rl-above, .03em) 0 -.08em -.12em; /* equal clear space above and below; the left pull
     lines the script's capital up with the edge of the lines around it */
  font-family: var(--font-script);
  font-weight: 400;
  font-variation-settings: normal;
  text-transform: none;
  font-size: calc(1.296em * var(--script-scale, 1)); /* 1.178em, then 10% bigger */
  line-height: 1;
  color: var(--accent-text);
}

.hero__title-script + .hero__title-line { margin-top: var(--rl-below, .24em); } /* breathing room under "Real Life" */

.hero__lede {
  max-width: 40ch;
  font-size: 1.0625rem;
  color: var(--text2);
}

/* Slightly tighter buttons so both fit on one line in narrow columns */
.hero__ctas .btn { padding-inline: 1.25rem; }
.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin-top: 2rem;
}

/* Stacked (phones, tablets): lower the portrait and colour block so the
   "Real Life" script has its own space above his head. */
@media (max-width: 1099px) {
  .hero__stage { min-height: clamp(480px, 130vw, 720px); }
  .hero__panel-img, .hero__conveyors { inset: 40% 0 0 0; }
  .portrait--hero { top: calc(var(--header-h) + clamp(3.25rem, 15vw, 6rem) * 1.1); }
}
@media (max-width: 599px) {
  /* Phones: a slightly tighter gap between "Real Life" and his head */
  /* head ~1/3 closer to "Real Life"; the photo area shortens by the same
     amount so the copy below rises into view */
  /* (then half again closer: .78 -> .47 closes half the remaining gap) */
  .portrait--hero { top: calc(var(--header-h) + clamp(3.25rem, 15vw, 6rem) * .47); }
  .hero__stage { min-height: calc(clamp(480px, 130vw, 720px) - clamp(3.25rem, 15vw, 6rem) * .125); }
}

/* Side by side from 1100px: Paul takes two thirds, the copy one third. */
@media (min-width: 1100px) {
  .hero {
    grid-template-columns: 2fr 1fr;
    grid-template-rows: 1fr;
    min-height: max(640px, calc(100svh - var(--review-h)));
  }
  .hero__stage { grid-column: 1; grid-row: 1; min-height: 0; }
  .hero__panel { grid-column: 2; grid-row: 1; }
  /* One chain of measurements so nothing collides at any window size:
     header -> "Real Life" -> top of Paul's head -> colour block -> copy.
     --headroom is the transparent space above his head in the photo
     (5.9% of the image x the image's 146.7% height). Re-measure it if the
     hero photo changes. */
  .hero {
    --script-size: calc(clamp(4.5rem, 8vw, 8.5rem) * var(--script-scale, 1));
    --script-top: calc(var(--header-h) + .45rem);                    /* even space under the header links */
    --head-top: calc(var(--script-top) + var(--script-size) * 1.261); /* clear gap under the script: .261 of its size (50% more than .174) */
    --headroom: 8.7%;
    --portrait-top: calc(var(--head-top) - var(--headroom));
    --block-top: calc(var(--head-top) + 11%);                        /* his head breaks above the block */
  }
  .hero__panel-img, .hero__conveyors { inset: var(--block-top) 0 0 0; }
  .hero__script { font-size: var(--script-size); top: var(--script-top); }
  .portrait--hero { top: var(--portrait-top); height: calc(88% / var(--portrait-keep)); left: 52%; }
  /* Copy starts level with the top of the colour block; the small offset
     lines up the first line's capitals rather than its box. */
  .hero__copy {
    position: absolute;
    top: calc(var(--block-top) - var(--name-cap-offset, .3rem));
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    padding: 0 clamp(1.75rem, 3vw, 3.25rem) 1.5rem;
  }
  /* Group 2 centres in the block height left below group 1 */
  .hero__main { margin-block: auto; padding-top: 1.5rem; }
  .hero__main .hero__title { margin-top: 0; }
  /* js/site.js shrinks it (--title-fit) if the longest line won't fit the column */
  .hero__copy { --hero-title-size: calc(clamp(2.1rem, 3.3vw, 3.25rem) * var(--display-scale, 1) * var(--title-fit, 1)); }
}

/* WORK -------------------------------------------------------------------- */
.work { padding-top: var(--section-pad); }
/* Side-by-side hero: its copy is centred in a full-height panel, so there is
   already open space above the hero's bottom edge; halve the top padding so
   the gap from the hero's buttons to this section matches other sections. */
/* Short desktop windows (laptops): "Real Life" 15% smaller; Paul is framed from his head (still
   just under "Real Life") down to just above his hands, with that crop
   line at the bottom of the colour block, and the name and headline are
   10% smaller. In the photo, his head starts 5.92% down and his hands at
   about 48.5%; the crop is at 47.5%. Width-only resizing never triggers this. */
@media (min-width: 1100px) and (max-height: 900px) {
  .hero { --script-size: calc(clamp(4.5rem, 8vw, 8.5rem) * .85 * var(--script-scale, 1)); } /* "Real Life" 15% smaller */
  .portrait--hero {
    --photo-h: calc((100% - var(--head-top)) / (.475 - .0592));
    height: var(--photo-h);
    top: calc(var(--head-top) - var(--photo-h) * .0592);
  }
  /* name and headline 10% smaller (still below the section headlines) */
  .hero__copy { --hero-title-size: calc(clamp(2.1rem, 3.3vw, 3.25rem) * .9 * var(--display-scale, 1) * var(--title-fit, 1)); }
}
@media (min-width: 1100px) {
  .work { padding-top: calc(var(--section-pad) * .5); }
  .contact { padding-bottom: calc(var(--section-pad) * .5); } /* last section before the footer */
}
.cross-type--work {
  top: 0;
  font-size: var(--divider-size);
  transform: translateY(-45%);
}

/* One gap, matching the space between the hero and this section's intro:
   intro -> cards, header -> pinned cards, cards -> disclaimer */
.work { --stack-gap: var(--head-gap); }
/* Desktop: headline and intro stacked on the left, the cards on the right */
@media (min-width: 1100px) {
  .work-pin {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: clamp(2rem, 4vw, 4rem);
    align-items: start; /* the eyebrow and the top card line up */
  }
  .work .section-head { margin-bottom: 0; }
  .work-pin .offer-stack { grid-column: 2; grid-row: 1 / span 2; }
  .work-pin .fine-print { grid-column: 1; grid-row: 2; align-self: end; } /* under the intro */
  .work .section-title { max-width: none; }
}
/* Offer cards. Static by default (a centred list); see the stack rules below. */
.offers { display: grid; gap: 1.5rem; list-style: none; justify-items: center; }
.offer {
  width: min(34rem, 100%);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius); /* matches the CTA buttons */
  box-shadow: 0 1px 2px rgb(0 0 0 / .06), 0 14px 34px -14px rgb(0 0 0 / .35);
}
.offer__head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.offer__num {
  font-family: var(--font-display);
  /* weight from the variable axis where the font has one; never synthesised */
  font-variation-settings: "wdth" 150, "wght" 900;
  font-weight: 400;
  font-size: clamp(2.25rem, 4vw, 3rem);
  line-height: .85;
  color: var(--brand);
}
.offer__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 115;
  font-weight: 800;
  font-size: calc(clamp(1.2rem, 2vw, 1.5rem) * var(--display-scale, 1));
  line-height: 1.1;
}
.offer__desc { color: var(--text2); }
.offer__for-label {
  margin: 1.25rem 0 .6rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text2);
}
.tags { display: flex; flex-wrap: wrap; gap: .5rem; list-style: none; }
.tags li {
  padding: .35rem .8rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: .875rem;
  line-height: 1.3;
}

/* Stacked cards (js/site.js adds .is-animated and .is-dropped). Each card
   drops in completely: shrinks from 135% and fades in, landing at its tilt. */
/* Pause (js/site.js adds .has-pause and sets --pause-top): from the Work
   section down, the page is one sticky sheet that holds still while the
   page scrolls through the travel space after it */
.pause__travel { display: none; }
html.has-pause .pause__page { position: sticky; top: var(--pause-top, 0px); }
html.has-pause .pause__travel { display: block; height: var(--travel, 140vh); } /* set by js/site.js */
/* Phones and tablets: if the cards would run off the bottom of the screen
   while paused, js/site.js adds .is-compact and the "Could include" tags
   are left out */
.offer-stack.is-compact :is(.offer__for-label, .tags) { display: none; }
/* Stacked in one grid cell, every card stretches to the tallest one's height, so
   the cards beneath never peek out larger than the one on top */
.offer-stack.is-animated .offers { display: grid; place-items: stretch center; width: 100%; }
.offer-stack.is-animated .offer {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translate(var(--spread, 0), var(--spread-y, 0)) rotate(calc(var(--tilt) * .4)) scale(1.35);
  transition: opacity .45s ease, transform .6s cubic-bezier(.2, .75, .3, 1);
}
.offer-stack.is-animated .offer.is-dropped { opacity: 1; transform: translate(var(--spread, 0), var(--spread-y, 0)) rotate(var(--tilt)) scale(1); }
/* Desktop: the stack fans out downwards, so each card's number and title
   peek out above the next one (01 at the top, 03 in front at the bottom) */
@media (min-width: 1100px) {
  .offer-stack.is-animated { --peek: 6.75rem; } /* room for a two-line title */
  /* the extra 1.25rem keeps the tilted corners (01's top, 03's bottom) inside the box */
  .offer-stack.is-animated .offers { padding-block: calc(var(--peek) + 1.25rem); }
  .offer-stack.is-animated .offer:nth-child(1) { --spread-y: calc(var(--peek) * -1); }
  .offer-stack.is-animated .offer:nth-child(3) { --spread-y: var(--peek); }
}
/* Phones and tablets: the cards in a row you swipe sideways (js/site.js
   adds .is-swipe below 1100px) */
/* the row scrolls sideways, which clips anything outside it, so it has room
   above and below for the cards' shadows (they reach about 34px down) */
.offer-stack.is-swipe .offers {
  display: flex; gap: .9rem; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none;
  margin-inline: calc(var(--gutter) * -1); padding: .75rem var(--gutter) 2.75rem;
  margin-bottom: -1.25rem;
}
.offer-stack.is-swipe .offers::-webkit-scrollbar { display: none; }
.offer-stack.is-swipe .offer { flex: 0 0 80%; scroll-snap-align: center; scroll-snap-stop: always; }
.swipe-dots { display: flex; justify-content: center; gap: .6rem; margin-top: .25rem; }
.swipe-dots button { width: .7rem; height: .7rem; padding: 0; border: 1px solid var(--text2); border-radius: 50%; background: transparent; cursor: pointer; }
.swipe-dots button[aria-current="true"] { background: var(--brand); border-color: var(--brand); }
.offer:nth-child(1) { --tilt: -4deg; }
.offer:nth-child(2) { --tilt: 0deg; }
.offer:nth-child(3) { --tilt: 3.5deg; }

/* 6. ABOUT ------------------------------------------------------------------ */
.about { background: var(--surface); }
.about__grid {
  display: grid;
  gap: clamp(3rem, 7vw, 6rem);
  align-items: start; /* text top-aligned with the photo, so "Read more" only grows downward */
}
.about__media { position: relative; }
.portrait--about {
  aspect-ratio: 4 / 5;
  background: var(--brand);
  overflow: hidden;
  width: 80%;        /* stacked layout: 20% smaller than the column */
  max-width: 27.2rem;
}
.portrait--about:not(.has-image)::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  opacity: .18;
  mix-blend-mode: multiply;
  pointer-events: none;
}
.portrait--about .portrait__silhouette { position: absolute; inset: auto 0 0 0; height: 88%; }
.portrait--about .portrait__caption { left: 1rem; top: 1rem; color: color-mix(in srgb, var(--brand-ink) 75%, transparent); }
.portrait--about.has-image img { object-fit: cover; object-position: 50% 30%; }

/* Type running horizontally over the photo and off the edge */
/* Cursive accent centred on the About photo, overhanging both edges by
   --over. "Experience" sets ~3.74em wide, so the font size is chosen to
   span the photo plus both overhangs. Over the photo it is the theme's light
   tone; past the edges it switches to --overhang-ink so it stays visible
   on light page backgrounds. */
.about__media { container-type: inline-size; }
.about__overlay {
  --img-w: min(80cqi, 27.2rem); /* matches .portrait--about */
  /* room between the photo and the screen edge (centred container + gutter) */
  --edge-room: calc((100vw - min(100vw, var(--maxw) + var(--gutter) * 2)) / 2 + var(--gutter) - 6px);
  /* the word runs past both photo edges; past the edges it turns brand colour */
  --over: min(calc(var(--img-w) * .15), var(--edge-room));
  position: absolute;
  left: calc(var(--over) * -1);
  width: calc(var(--img-w) + var(--over) * 2);
  bottom: 7%;
  z-index: 3;
  display: grid;
  pointer-events: none;
  user-select: none;
  font-family: var(--font-script);
  font-size: calc((var(--img-w) + var(--over) * 2) / 3.74 / var(--script-width, 1)); /* same width in any script face */
  line-height: 1.15;
}
/* Phones: no room to overhang, so the word fits inside the photo, its
   letters (not their box) nearly touching the edges */
@media (max-width: 599px) {
  .about__overlay { --over: calc(var(--img-w) * .012); }
  .about__overlay-layer--out { display: none; }
}
.about__overlay-layer { grid-area: 1 / 1; text-align: center; white-space: nowrap; }
/* The script's ink sits right of its text box (the final "e" swings out),
   so nudge it left to make the two overhangs even */
.about__overlay-layer span { display: inline-block; transform: translateX(var(--ink-shift, -.085em)) rotate(-8deg); } /* --ink-shift: per script face, js/theme-boot.js */
.about__overlay-layer--in {
  color: var(--paper);
  clip-path: inset(-50% var(--over) -50% var(--over)); /* only over the photo */
  text-shadow: 0 .04em .3em rgb(0 0 0 / .35);
}
.about__overlay-layer--out {
  /* The box reaches .5em past every side so tilted letters (a sloping "E",
     a long tail) are never cut off by the mask's edge; the mask shows only
     what lies past the photo */
  --pad: .5em;
  margin: calc(var(--pad) * -1);
  padding: var(--pad);
  color: var(--overhang-ink);
  -webkit-mask: linear-gradient(90deg, #000 calc(var(--pad) + var(--over)), transparent calc(var(--pad) + var(--over)), transparent calc(100% - var(--pad) - var(--over)), #000 calc(100% - var(--pad) - var(--over)));
  mask: linear-gradient(90deg, #000 calc(var(--pad) + var(--over)), transparent calc(var(--pad) + var(--over)), transparent calc(100% - var(--pad) - var(--over)), #000 calc(100% - var(--pad) - var(--over)));
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

.about__text .section-title { max-width: none; font-size: calc(clamp(2rem, 4vw, 3.4rem) * var(--display-scale, 1)); }
/* Name on one line where the column allows: the size shrinks to fit the
   column (cqi = 1% of its width); phones wrap instead. */
.about__text { container-type: inline-size; }
@media (min-width: 600px) {
  .about__text .about__name {
    white-space: nowrap;
    font-size: min(calc(clamp(2rem, 4vw, 3.4rem) * var(--display-scale, 1)), 4.6cqi);
  }
}
.about__script {
  margin: var(--script-above, 0) 0 var(--script-below, 0) -.12em; /* the left pull lines the "T" up with the title */
  font-family: var(--font-script);
  font-size: calc(clamp(1.84rem, 2.99vw, 2.53rem) * var(--script-scale, 1)); /* 15% over 1.6rem / 2.6vw / 2.2rem */
  line-height: 1.2;
  color: var(--accent-text);
}

.story-toggle {
  display: inline-flex;
  align-items: center;
  gap: .9rem;
  margin-top: 2rem;
  padding: .5rem 0;
  border: 0;
  border-bottom: 2px solid var(--cta); /* an action, so the CTA colour */
  background: none;
  color: var(--cta);
  font-weight: 600;
  font-size: 1.0625rem;
  cursor: pointer;
}
.story-toggle:hover { border-bottom-width: 3px; }


/* Story dialog: three chapters, photos alternating sides on desktop */
html.has-dialog { overflow: hidden; }
.story-dialog {
  width: min(64rem, calc(100vw - 2rem));
  max-height: calc(100svh - 2rem);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  overflow: hidden; /* only the inner area scrolls, so the close button never moves */
}
.story-dialog[open] { display: flex; flex-direction: column; }
.story-dialog::backdrop { background: rgb(0 0 0 / .6); }
.story-dialog__inner {
  --dlg-gap: clamp(2.5rem, 6vw, 4.5rem);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  gap: var(--dlg-gap);
  padding: clamp(1.5rem, 5vw, 3.5rem);
}
.story-dialog__close {
  position: absolute;
  top: .9rem;
  right: .9rem;
  z-index: 2;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--bg);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
.story-dialog__head .section-title { margin: 0; }
.story-dialog__head { padding-right: 3rem; } /* clear of the close button */
/* Pull quotes: a line from Paul's text repeated large in the handwritten
   script, centred between sections. Screen readers skip the repeat. */
.pull-quote { margin: 0 auto; max-width: 38rem; text-align: center; }
.pull-quote p {
  margin: 0;
  font-family: var(--font-script);
  font-size: calc(clamp(1.9rem, 3.6vw, 2.75rem) * var(--script-scale, 1));
  line-height: 1.25;
  letter-spacing: var(--script-tracking, normal);
  color: var(--accent-text);
  text-wrap: balance;
}
.chapter p strong { color: var(--text); font-weight: 600; }
/* The second piece: its own title, after a rule */
.story-part { padding-top: var(--dlg-gap); border-top: 1px solid var(--line-strong); }
.story-part__title {
  margin: 0;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 115;
  font-weight: 800;
  font-size: calc(clamp(1.7rem, 3.4vw, 2.6rem) * var(--display-scale, 1));
  line-height: 1.05;
  word-spacing: var(--display-word-spacing, normal);
  color: var(--brand);
  text-wrap: balance;
}
/* Chapters: newspaper-style wrap. The photo floats beside the text, which
   continues full width beneath it; sides alternate. Phones: photo on top. */
.chapter::after { content: ""; display: block; clear: both; }
.chapter p { max-width: none; }
.chapter p + p { margin-top: 1em; }
.chapter__photo { margin: 0 0 1.25rem; border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.chapter__photo img { width: 100%; height: auto; display: block; }
.chapter__photo--pending { display: grid; place-items: center; aspect-ratio: 4 / 3; }
.chapter__photo--pending.has-image { display: block; aspect-ratio: auto; }
.chapter__photo-fallback { font-family: var(--font-script); font-size: 2rem; color: var(--text2); }
.chapter__photo.has-image .chapter__photo-fallback { display: none; }
.chapter__photo--small { width: 80%; margin-inline: auto; } /* 20% smaller than its neighbours */
.chapter__title {
  margin-bottom: 1rem;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 115;
  font-weight: 800;
  font-size: calc(clamp(1.3rem, 2.4vw, 1.8rem) * var(--display-scale, 1));
  word-spacing: var(--display-word-spacing, normal);
  color: var(--brand);
}
.story__slot { color: var(--text2); font-style: italic; }
@media (min-width: 900px) {
  /* 4 of 11 parts: the photo column at 80% of its former 5 parts, the text takes the rest */
  .about__grid { grid-template-columns: 4fr 7fr; }
  .portrait--about { width: 100%; }
  .about__overlay { --img-w: min(100cqi, 27.2rem); }
}
@media (min-width: 760px) {
  .chapter__photo { float: left; width: 46%; margin: .35rem 2rem 1rem 0; }
  .chapter--flip .chapter__photo { float: right; margin: .35rem 0 1rem 2rem; }
  .chapter__photo--tall { width: 34%; } /* portrait-shaped photos, so text wraps beneath sooner */
  .chapter__photo--small { width: 27.2%; }
}

/* 7. APPEARANCES ----------------------------------------------------------- */
.cross-type--voices {
  top: 0;
  font-size: var(--divider-size);
  transform: translateY(-45%);
}
.appearances { --stack-gap: var(--head-gap); }
@media (min-width: 1100px) {
  .appearances .section-head--split { grid-template-columns: 1fr; } /* no intro beside it */
  #appearances-title { max-width: none; }
  #appearances-title br { display: none; } /* one line on desktop */
} /* cards -> fine print, as in Work */
.appearances__rail {
  display: grid;
  gap: 1.25rem;
  align-items: stretch;
  /* equal heights only matter side by side (set below); stacked cards fit their content */
  list-style: none;
}
@media (min-width: 760px) {
  .appearances__rail { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1.5rem; }
}
@media (min-width: 1100px) {
  .appearances__rail { grid-template-columns: repeat(3, 1fr); } /* one row of three */
}

/* More than three: a sliding row on desktop, "Load more" below that */
.appearances__carousel { position: relative; container-type: inline-size; }
.appearances__more { display: flex; justify-content: center; }
.appearances__more .btn { margin-top: 1.5rem; }
.appearances__arrow {
  display: none;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}
.appearances__arrow svg { width: 1.25rem; height: 1.25rem; }
.appearances__arrow:hover, .appearances__arrow:focus-visible { background: var(--cta); border-color: var(--cta); color: var(--cta-ink); }
.has-carousel .appearances__rail > li.is-more { display: none; } /* phones and tablets: not loaded yet */
.appearances__rail > li.is-clone { display: none; } /* copies for the desktop loop */
@media (min-width: 1100px) {
  .has-carousel .appearances__more { display: none; }
  .has-carousel .appearances__rail > li.is-more { display: flex; }
  .is-autoplay .appearances__rail > li.is-clone { display: flex; }
  /* the moving row runs out to the page's edges and fades there, instead
     of being cut off at the content column; it starts lined up with it */
  .has-carousel.is-autoplay .appearances__viewport {
    margin-left: calc(-1 * var(--edge-l, 0px));
    margin-right: calc(-1 * var(--edge-r, 0px));
    padding-left: var(--edge-l, 0px);
    padding-right: var(--edge-r, 0px);
    -webkit-mask: linear-gradient(90deg, transparent, #000 var(--edge-l, 0px), #000 calc(100% - var(--edge-r, 0px)), transparent);
    mask: linear-gradient(90deg, transparent, #000 var(--edge-l, 0px), #000 calc(100% - var(--edge-r, 0px)), transparent);
  }
  .is-autoplay .appearances__arrow { display: none !important; }
  .has-carousel .appearances__viewport { overflow: hidden; margin: -.5rem; padding: .5rem; } /* room for focus rings */
  .has-carousel .appearances__rail {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - 3rem) / 3);
    transform: translateX(calc(var(--shift, 0) * -1 * ((100% - 3rem) / 3 + 1.5rem)));
    transition: transform .6s cubic-bezier(.3, .7, .2, 1);
  }
  /* midway between the page edge and the cards (js/site.js measures the
     margins), level with the middle of the logo tiles */
  .has-carousel .appearances__arrow:not([hidden]) {
    display: grid;
    position: absolute;
    top: calc((100cqw - 3rem) / 3 * 9 / 32);
    translate: 0 -50%;
    z-index: 2;
  }
  /* a little smaller where the margin is narrow, so it never touches either side */
  .appearances__arrow--prev { --size: clamp(2rem, calc(var(--edge-l, var(--gutter)) - 1.25rem), 2.75rem); left: calc(var(--edge-l, var(--gutter)) / -2 - var(--size) / 2); }
  .appearances__arrow--next { --size: clamp(2rem, calc(var(--edge-r, var(--gutter)) - 1.25rem), 2.75rem); right: calc(var(--edge-r, var(--gutter)) / -2 - var(--size) / 2); }
  .has-carousel .appearances__arrow:not([hidden]) { width: var(--size); height: var(--size); }
}
@media (prefers-reduced-motion: reduce) { .appearances__rail { transition: none !important; } }
.appearance {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
}
/* The logo leads: a large, neutral tile so any partner logo reads cleanly */
.appearance__logo {
  position: relative;
  overflow: hidden; /* keeps the zooming hover photo inside the tile */
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background: color-mix(in srgb, var(--text) 5%, var(--bg));
  border-bottom: 1px solid var(--line);
}
.appearance__logo::before { /* sparse pattern so the empty tile still looks intentional */
  content: "";
  position: absolute;
  inset: 0;
  background: var(--text);
  opacity: .05;
  -webkit-mask: var(--pattern);
  mask: var(--pattern);
}
.appearance__logo img {
  position: absolute;
  top: 12%;
  left: 10%;
  width: 80%;
  height: 76%;
  object-fit: contain;
}
/* Per-card logo size (the tile's logo box is the same for every card) */
.appearance--buntport .appearance__logo img:not(.appearance__hover-photo) { transform: scale(.834); }
.appearance--savoy .appearance__logo img:not(.appearance__hover-photo) { transform: translateY(6.6%) scale(.665); } /* 5% of the tile lower (the box is 76% of it) */
.appearance--kgnu .appearance__logo img:not(.appearance__hover-photo) { transform: scale(.757); } /* .67, then 13% bigger */
/* Real logos sit on white so their own colours are respected in every theme */
.appearance__logo.has-image { background: #fff; }
.appearance__logo.has-image::before,
.appearance__logo.has-image .appearance__logo-fallback { display: none; }
.appearance__logo-fallback {
  position: relative;
  display: grid;
  justify-items: center;
  gap: .6rem;
  text-align: center;
}
.appearance__logo-name {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 120;
  font-weight: 300;
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.05;
  color: var(--text2);
}
.appearance__logo-tag {
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--text2) 75%, transparent);
}
/* Desktop hover: the logo fades to the event photo, which slowly zooms
   (and pans, per card) to a set point and holds there. */
.appearance__logo img { transition: opacity .5s ease; }
.appearance__logo .appearance__hover-photo {
  transform: var(--zoom-from, none);
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  object-fit: cover;
  opacity: 0;
  transform-origin: var(--origin, 50% 50%);
  transition: opacity .6s ease, transform .9s ease;
}
.appearance--podcast { --origin: 51% 36%; --zoom-to: scale(1.22); --zoom-time: 6s; }                        /* toward Paul's face */
/* Buntport starts 35% of the way into the zoom, so it travels less and moves more gently */
/* Group photo: zoomed in, with the front panelist's shirt collar at the
   centre of the tile (object-position keeps the top of the photo; the
   translate moves that point to the middle). */
.appearance__logo .appearance__hover-photo--after {
  object-position: var(--after-position, 50% 50%);
  transform-origin: var(--after-origin, 50% 50%);
  transform: var(--after-transform, none);
  transition: opacity .3s ease;
}
.appearance--buntport { --origin: 50% 50%; --zoom-from: translate(-13.65%, -3.15%) scale(1.28); --zoom-to: translate(-39%, -9%) scale(1.8); --zoom-time: 5s; /* pans right to Paul, seated far right */
  --after-position: 50% 0%; --after-origin: 47% 44%; --after-transform: translate(2.4%, -1.8%) scale(1.35); /* group centred in the tile */ }
/* Savoy: starts close and pulls back to the whole photo of Paul and his portrait display, then the panel, framed on Paul (second from left) */
.appearance--kgnu { --origin: 50% 45%; --zoom-from: scale(1.22); --zoom-to: scale(1); --zoom-time: 6s; } /* zooms out at the podcast card's pace (.22 in 6s) */
.appearance--savoy { --origin: 50% 56%; --zoom-from: scale(1.4); --zoom-to: scale(1); --zoom-time: 5s; /* zooms out, ending on the full frame */
  --after-origin: 38% 42%; --after-transform: scale(1.45); }
@media (hover: hover) and (pointer: fine) {
  .appearance.has-hover-photo:hover .appearance__logo .appearance__hover-photo {
    opacity: 1;
    transform: var(--zoom-to);
    transition: opacity .6s ease, transform var(--zoom-time) cubic-bezier(.3, .1, .3, 1);
  }
  .appearance.has-hover-photo:hover .appearance__logo img:not(.appearance__hover-photo) { opacity: 0; }
  /* Cards with a second photo (Buntport, Savoy): as soon as the zoom lands, a quick fade to the
     second photo */
  .appearance.has-hover-photo:hover .appearance__logo .appearance__hover-photo--after {
    transform: var(--after-transform, none);
    transition: opacity .35s ease var(--zoom-time); /* starts the moment the zoom lands */
  }
}
/* Touch screens (no hover): the same sequence plays once the card's image
   scrolls above the lower two fifths of the screen (js/site.js adds
   .is-playing), and rewinds to the logo below that line */
@media (hover: none), (pointer: coarse) {
  .appearance.has-hover-photo.is-playing .appearance__logo .appearance__hover-photo {
    opacity: 1;
    transform: var(--zoom-to);
    transition: opacity .6s ease, transform var(--zoom-time) cubic-bezier(.3, .1, .3, 1);
  }
  .appearance.has-hover-photo.is-playing .appearance__logo img:not(.appearance__hover-photo) { opacity: 0; }
  /* Cards with a second photo (Buntport, Savoy): as soon as the zoom lands, a quick fade to the
     second photo */
  .appearance.has-hover-photo.is-playing .appearance__logo .appearance__hover-photo--after {
    transform: var(--after-transform, none);
    transition: opacity .35s ease var(--zoom-time); /* starts the moment the zoom lands */
  }
}
@media (prefers-reduced-motion: reduce) {
  .appearance__logo .appearance__hover-photo { transform: none !important; }
}
.appearance__body { flex: 1; display: flex; flex-direction: column; align-items: flex-start; padding: 1.5rem 1.75rem 1.75rem; }
.appearance__title {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 110;
  font-weight: 800;
  font-size: calc(1.4rem * var(--display-scale, 1));
  line-height: 1.15;
}
.appearance__role {
  margin: .4rem 0 .75rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--brand);
}
.appearance__role cite { font-style: italic; text-transform: none; letter-spacing: .02em; font-size: 1.08em; }
.appearance__detail { max-width: 46ch; color: var(--text2); }
.appearance__link {
  display: inline-block;
  margin-top: auto; /* sits at the bottom of the card */
  padding-top: 1rem;
  font-size: .875rem;
  font-weight: 600;
}
.appearance__link.is-pending { color: var(--text2); }
a.appearance__link { color: var(--cta); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em; }
a.appearance__link:hover { text-decoration-thickness: 2px; }

/* 8. CASE STUDIES -------------------------------------------------------- */
.cases { background: var(--surface); }
.cases__grid {
  display: grid;
  gap: 1.25rem;
}
@media (min-width: 900px) {
  .cases__grid { grid-template-columns: 1.5fr 1fr; grid-template-rows: 1fr 1fr; }
  .case--feature { grid-row: 1 / span 2; }
}
.case {
  position: relative;
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  border-radius: var(--radius);
  background: var(--bg);
  border: 1px solid var(--line);
  overflow: hidden;
}
.case--feature { border-top: 4px solid var(--brand); }
.case__title {
  margin: 1.25rem 0 1.5rem;
  font-family: var(--font-display);
  font-variation-settings: "wdth" 115;
  font-weight: 800;
  font-size: calc(clamp(1.4rem, 2.6vw, 2.1rem) * var(--display-scale, 1));
  line-height: 1.08;
}
.case__fields { display: grid; gap: 1.25rem; }
.case__fields div { padding-top: 1rem; border-top: 1px solid var(--line); }
.case__fields dt {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: .35rem;
}
.case__summary { color: var(--text2); font-size: .9375rem; }
/* Empty state: template text reads clearly as a template */
.case.is-empty .case__field { color: var(--text2); }
.case.is-empty .case__title .case__field { color: color-mix(in srgb, var(--text) 45%, transparent); }

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .75rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.status-badge__dot {
  width: .5rem; height: .5rem;
  border-radius: 50%;
  border: 2px solid var(--brand);
}

/* 9. REVIEWS --------------------------------------------------------------- */
.reviews__grid {
  display: grid;
  gap: 1.25rem;
  list-style: none;
}
@media (min-width: 760px) { .reviews__grid { grid-template-columns: repeat(3, 1fr); } }
.review {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 17rem;
  padding: 1.75rem;
  border-radius: var(--radius);
  border: 1px dashed var(--line-strong);
}
.review__mark {
  font-family: var(--font-display);
  font-variation-settings: "wdth" 150;
  font-weight: 900;
  font-size: 4.5rem;
  line-height: .8;
  color: var(--brand);
  opacity: .55;
}
.review__empty {
  margin-top: 1rem;
  font-weight: 600;
  font-size: 1.125rem;
}
.review__lines { display: grid; gap: .6rem; margin: 1.25rem 0 auto; }
.review__lines i {
  display: block;
  height: .55rem;
  border-radius: 99px;
  background: color-mix(in srgb, var(--text) 8%, transparent);
}
.review__lines i:nth-child(2) { width: 88%; }
.review__lines i:nth-child(3) { width: 62%; }
.review__who-empty {
  margin-top: 1.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  font-size: .875rem;
  color: var(--text2);
}

/* 10. CONTACT -------------------------------------------------------------- */
.contact { background: var(--surface); overflow-y: visible; }
.cross-type--talk {
  top: 0;
  font-size: var(--divider-size);
  transform: translateY(-45%);
  z-index: 3;
}
.contact__texture {
  position: absolute;
  inset: 0;
  background: var(--text);
  opacity: .06;
  -webkit-mask: var(--pattern), linear-gradient(200deg, transparent 55%, #000 100%);
  -webkit-mask-composite: source-in;
  mask: var(--pattern), linear-gradient(200deg, transparent 55%, #000 100%);
  mask-composite: intersect;
  pointer-events: none;
}
.contact__grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
}
@media (min-width: 960px) {
  /* Intro top left, the form on the right, and the social links in the left
     column's bottom, lined up with the form's bottom edge */
  .contact__grid { grid-template-columns: 1fr 1.15fr; grid-template-rows: auto 1fr; align-items: start; }
  .contact__intro { grid-column: 1; grid-row: 1; }
  .contact-form { grid-column: 2; grid-row: 1 / span 2; }
  .contact__social { grid-column: 1; grid-row: 2; align-self: end; }
}

/* Social links: a script line over round icon buttons in the brand colours */
.contact__social-title {
  margin: 0 0 .9rem;
  font-family: var(--font-script);
  font-size: calc(clamp(1.725rem, 2.76vw, 2.3rem) * var(--script-scale, 1)); /* as "wherever you're starting from" */
  line-height: 1.2;
  color: var(--accent-text);
}
.social-links { display: flex; gap: .75rem; margin: 0; padding: 0; list-style: none; }
.social-link {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--brand);
  color: var(--brand-ink);
  transition: background-color .2s ease, color .2s ease;
}
.social-link svg { width: 1.35rem; height: 1.35rem; fill: currentColor; }
.social-link:hover, .social-link:focus-visible { background: var(--cta); color: var(--cta-ink); }
.contact__script {
  margin: var(--script-above, 0) 0 var(--script-below, 0);
  font-family: var(--font-script);
  font-size: calc(clamp(1.725rem, 2.76vw, 2.3rem) * var(--script-scale, 1)); /* 15% over 1.5rem / 2.4vw / 2rem */
  color: var(--accent-text);
}
.contact__script + .section-intro { margin-top: 0; }
/* Cursive taglines: the same clear space above (to the headline) and below
   (to the text). Margins offset each title's own
   line spacing, so the visible gaps match. */
:root { --script-gap: clamp(1rem, 2vw, 1.5rem); }
.about__script, .contact__script { width: fit-content; }
.about__script { --script-above: calc(var(--script-gap) * .5 - .1rem); --script-below: calc(var(--script-gap) - .55rem); }
.contact__script { --script-above: -.15rem; --script-below: calc(var(--script-gap) - 1.1rem); }

.contact-form {
  display: grid;
  gap: 1.25rem;
  padding: clamp(1.5rem, 4vw, 2.75rem);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
@media (min-width: 600px) {
  .contact-form { grid-template-columns: 1fr 1fr; }
  .field--full, .form-status { grid-column: 1 / -1; }
}
.field label {
  display: block;
  margin-bottom: .45rem;
  font-weight: 600;
  font-size: .9375rem;
}
.req { color: var(--accent-text); }
.field__optional { font-weight: 400; color: var(--text2); }
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 3rem;
  padding: .75rem .9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  color: var(--text);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.field textarea { resize: vertical; min-height: 9rem; }
.field input::placeholder, .field textarea::placeholder { color: color-mix(in srgb, var(--text2) 70%, transparent); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--accent-text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cta) 35%, transparent);
}
.field [aria-invalid="true"] { border-color: #e5484d; }
.field__error {
  margin-top: .35rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--text);
}
.field__error:not(:empty)::before { content: "! "; color: #e5484d; font-weight: 800; }
.field__error:empty { display: none; }
.select { position: relative; }
.select select { appearance: none; padding-right: 2.5rem; }
.select::after {
  content: "";
  position: absolute;
  right: 1rem; top: 50%;
  width: .5rem; height: .5rem;
  border-right: 2px solid var(--text2);
  border-bottom: 2px solid var(--text2);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.field select option { background: var(--bg); color: var(--text); }

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.req-note { font-size: .875rem; color: var(--text2); }
.form-status:empty { display: none; }
.form-status {
  padding: 1rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: .9375rem;
}
.form-status strong { display: block; margin-bottom: .25rem; }
.form-status.is-warn { border-color: var(--cta); }
.form-status.is-ok { border-color: var(--brand); }

/* 11. FOOTER ----------------------------------------------------------------- */
.site-footer { padding-block: 1.75rem; font-size: .875rem; }
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4rem 1.5rem;
}
.site-footer__name { color: var(--text); }
.site-footer__legal { margin-left: auto; font-size: .8125rem; color: var(--text2); }
@media (max-width: 759px) { .site-footer__legal { margin-left: 0; width: 100%; } }

/* 12. MOTION ----------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity .7s ease, transform .7s cubic-bezier(.2, .7, .2, 1);
  }
  .js .reveal.is-in { opacity: 1; transform: none; }

  .js:not(.is-loading) .hero__script { animation: fade 1.2s .4s ease both; }
  .js:not(.is-loading) .portrait--hero { animation: rise-portrait 1.1s cubic-bezier(.2, .7, .2, 1) both; }
  .js:not(.is-loading) .hero__copy > * { animation: fade-up .8s cubic-bezier(.2, .7, .2, 1) both; }
  .js:not(.is-loading) .hero__copy > :nth-child(2) { animation-delay: .15s; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes rise-portrait { from { opacity: 0; transform: translate(-50%, 24px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* 13. PLACEHOLDER MARKERS ------------------------------------------------------
   Anything unconfirmed carries data-ph="copy|fact|asset|content" and an
   optional data-ph-note="Short label" in index.html. They have no visual
   effect; list them with:  grep -n 'data-ph=' index.html
   Remove both attributes once an item is approved. */
:root { --rv: #e0127a; } /* review-toolbar accent, independent of the theme */

/* 14. DESIGN REVIEW TOOLBAR -----------------------------------------------------
   Own fixed palette so it never changes with the theme. */
.rv-bar {
  --rv-bg: #1c1c21;
  --rv-bg2: #26262d;
  --rv-fg: #f2f2f5;
  --rv-fg2: #a7a7b3;
  --rv-line: #3a3a44;
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--rv-bg);
  color: var(--rv-fg);
  font: 500 13px/1.3 var(--font-body);
  border-bottom: 2px solid var(--rv);
}
.rv-bar :focus-visible { outline: 2px solid #ff7ab8; outline-offset: 2px; }
.rv-bar__row {
  display: flex;
  align-items: center;
  gap: .5rem 1rem;
  min-height: 40px;
  padding: 4px var(--gutter);
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
}
.rv-bar__title {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: 11px;
  white-space: nowrap;
}
.rv-bar__title::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--rv);
}
.rv-bar__spacer { flex: 1; }
.rv-btn {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  min-height: 30px;
  padding: 4px 10px;
  border: 1px solid var(--rv-line);
  border-radius: 6px;
  background: var(--rv-bg2);
  color: var(--rv-fg);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.rv-btn:hover { border-color: var(--rv-fg2); }
.rv-btn__chev { transition: transform .2s ease; font-size: 10px; }
.rv-btn[aria-expanded="true"] .rv-btn__chev { transform: rotate(180deg); }

/* Vertical drawer on the right: Colour, Font, Pattern, separated by rules */
.rv-panel {
  position: absolute;
  top: 100%;
  right: 0;
  width: min(380px, 100vw);
  max-height: calc(100svh - 44px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--rv-bg);
  border-left: 1px solid var(--rv-line);
  border-bottom: 2px solid var(--rv);
  box-shadow: -18px 18px 40px rgb(0 0 0 / .45);
}
.rv-section {
  display: grid;
  gap: .6rem;
  padding: 1rem 1.1rem 1.15rem;
}
.rv-section + .rv-section { border-top: 1px solid var(--rv-line); }
.rv-section__title {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--rv-fg);
}
.rv-sub {
  margin: .35rem 0 0;
  font-size: 11px;
  color: var(--rv-fg2);
}
.rv-list { display: grid; gap: 4px; }
.rv-details { margin-top: .4rem; border-top: 1px dashed var(--rv-line); padding-top: .6rem; }
.rv-details summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--rv-fg);
  padding: 4px 0;
}
.rv-details__body { display: grid; gap: .6rem; margin-top: .6rem; }

/* One row per choice (themes, patterns) */
.rv-option {
  display: flex;
  align-items: center;
  gap: .65rem;
  width: 100%;
  min-height: 36px;
  padding: 6px 10px 6px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--rv-fg);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rv-option:hover { background: var(--rv-bg2); }
.rv-option[aria-pressed="true"] { background: var(--rv-bg2); border-color: #fff; }
.rv-option__check { margin-left: auto; font-size: 12px; opacity: 0; }
.rv-option[aria-pressed="true"] .rv-option__check { opacity: 1; }
.rv-option__edited { font-size: 10px; color: #ff7ab8; }
.rv-sw { display: inline-flex; flex: none; border-radius: 3px; overflow: hidden; border: 1px solid rgb(255 255 255 / .2); }
.rv-sw i { width: 9px; height: 18px; }
.rv-pattern-sw {
  flex: none;
  width: 36px;
  height: 22px;
  border-radius: 3px;
  background: var(--rv-fg2);
  -webkit-mask: var(--sw);
  mask: var(--sw);
}
.rv-pattern-sw--panel { -webkit-mask: var(--sw) right center / auto 100% no-repeat; mask: var(--sw) right center / auto 100% no-repeat; background: var(--rv-fg); }
.rv-pattern-sw--none { -webkit-mask: none; mask: none; background: transparent; border: 1px dashed var(--rv-line); }

/* Labelled controls stacked one per row (fonts, colours) */
.rv-field { display: grid; gap: .3rem; }
.rv-field label { font-size: 12px; color: var(--rv-fg2); }
/* Minimize: the bar folds into a small box floating at the top right (under the header),
   over the page (it no longer pushes anything down), keeping the saved
   choice chips and a button to expand it again */
.rv-btn--icon { width: 30px; padding: 0; justify-content: center; }
.rv-icon { width: 16px; height: 16px; }
.rv-icon--max, html[data-review-min] .rv-icon--min { display: none; }
html[data-review-min] .rv-icon--max { display: block; }
html[data-review-min] .rv-bar {
  position: fixed;
  top: calc(var(--header-h) + 10px); /* just under the site header, clear of its menu and button */
  right: 10px;
  border: 2px solid var(--rv);
  border-radius: 10px;
  box-shadow: 0 10px 30px rgb(0 0 0 / .35);
}
html[data-review-min] .rv-bar__row { min-height: 0; padding: 4px; gap: 4px; max-width: none; }
html[data-review-min] :is(.rv-bar__title, .rv-bar__spacer, #rv-toggle) { display: none; }

/* Font picker: a button per family, set in its own face, with variant toggles */
.rv-field__label { font-size: 12px; color: var(--rv-fg2); }
.rv-fonts { display: grid; gap: 4px; }
.rv-font { display: grid; gap: 4px; }
.rv-font__name { font-size: 17px; line-height: 1.2; }
.rv-variants { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 0 4px 10px; }
.rv-variant {
  padding: 4px 8px; border: 1px solid var(--rv-line); border-radius: 999px;
  background: transparent; color: var(--rv-fg2); font: 500 11px/1.2 var(--font-body); cursor: pointer;
}
.rv-variant:hover { color: var(--rv-fg); border-color: var(--rv-fg2); }
.rv-variant[aria-pressed="true"] { background: var(--rv-fg); border-color: var(--rv-fg); color: var(--rv-bg); }

/* Saved choices: numbered chips in the bar, list in the drawer */
.rv-chips { display: flex; gap: 4px; }
.rv-chip {
  min-width: 28px;
  height: 28px;
  padding: 0 6px;
  border: 1px solid var(--rv-line);
  border-radius: 6px;
  background: var(--rv-bg2);
  color: var(--rv-fg);
  font: 600 12px/1 var(--font-body);
  cursor: pointer;
}
.rv-chip[aria-pressed="true"] { background: var(--rv); border-color: var(--rv); color: #fff; }
.rv-choice {
  display: flex; align-items: center; gap: 2px;
  padding-left: 6px;
  border: 1px solid var(--rv-line);
  border-radius: 6px;
  background: var(--rv-bg2);
}
.rv-choice:has(.rv-option[aria-pressed="true"]) { border-color: #fff; }
.rv-choice .rv-option { flex: 1; min-width: 0; flex-wrap: wrap; row-gap: 2px; border: 0; background: transparent; padding-left: 4px; }
.rv-choice__desc { flex-basis: 100%; order: 3; font-size: 11px; color: var(--rv-fg2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-choice__del {
  flex: none;
  width: 28px; height: 28px;
  border: 1px solid var(--rv-line);
  border-radius: 50%;
  background: transparent;
  color: var(--rv-fg);
  font: 400 18px/1 var(--font-body);
  cursor: pointer;
}
.rv-choice__del:hover, .rv-choice__del:focus-visible { background: #c43d3d; border-color: #c43d3d; color: #fff; }
.rv-btn--accent { background: var(--rv); border-color: var(--rv); color: #fff; }
.rv-range { margin-top: .5rem; }
.rv-range label { display: flex; justify-content: space-between; }
.rv-range output { color: var(--rv-fg); font-variant-numeric: tabular-nums; }
.rv-range input { width: 100%; accent-color: var(--rv); }
.rv-field select {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--rv-line);
  border-radius: 4px;
  background: var(--rv-bg2);
  color: var(--rv-fg);
  font: 500 14px/1.3 var(--font-body);
}
.rv-color {
  display: grid;
  grid-template-columns: 30px 1fr 88px;
  align-items: center;
  gap: .6rem;
}
.rv-color label { font-size: 12px; color: var(--rv-fg2); }
.rv-color input[type="color"] {
  width: 30px; height: 30px;
  padding: 0;
  border: 1px solid var(--rv-line);
  border-radius: 4px;
  background: none;
  cursor: pointer;
}
.rv-color input[type="text"] {
  width: 100%;
  min-width: 0;
  padding: 4px 6px;
  border: 1px solid var(--rv-line);
  border-radius: 4px;
  background: var(--rv-bg2);
  color: var(--rv-fg);
  font: 500 13px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  text-transform: lowercase;
}
.rv-color input[aria-invalid="true"] { border-color: var(--rv); }
.rv-contrast { margin: .25rem 0 0; font-size: 12px; line-height: 1.45; color: var(--rv-fg2); }
.rv-contrast b { color: var(--rv-fg); font-weight: 600; }
.rv-contrast .is-low { color: #ff7ab8; }
.rv-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.rv-hint { margin: 0; font-size: 12px; line-height: 1.45; color: var(--rv-fg2); }
.rv-hint code { color: var(--rv-fg); }

@media (max-width: 640px) {
  .rv-bar__row { gap: .4rem; padding-inline: .75rem; }
  .rv-hide-sm { display: none; }
  .rv-bar__title { font-size: 10px; }
}
