/* ==========================================================================
   Ycotes — component library.
   Every value comes from tokens.css. No raw hex below this line: if a colour
   is needed that isn't a token, the token set is wrong, not this file.
   Mobile-first. No framework.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-padding-top: 5.5rem; }

body {
  margin: 0;
  background: var(--surface-0);
  color: var(--text-mid);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  /* Belt and braces against the horizontal scroll that parallax can cause. */
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--text-hi);
  line-height: var(--lh-snug);
  margin: 0 0 var(--s-4);
  font-weight: 500;              /* large + calm beats medium + shouting */
  text-wrap: balance;
}
h1 { font-size: var(--fs-hero); line-height: var(--lh-tight); letter-spacing: var(--tracking-hero); }
h2 { font-size: var(--fs-h2);  letter-spacing: -0.02em; }
h3 { font-size: var(--fs-h3);  letter-spacing: -0.01em; }

p { margin: 0 0 var(--s-4); max-width: var(--measure); text-wrap: pretty; }

a { color: inherit; text-decoration-color: color-mix(in srgb, var(--y-yellow) 55%, transparent);
    text-underline-offset: 0.2em; transition: color var(--dur-fast) var(--ease-out); }
a:hover { color: var(--accent-ink); }

img, video, svg { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0; padding: 0; list-style: none; }

/* The [hidden] attribute loses to any class that sets `display`. Without this
   both nav panels render at once. Must sit above the component rules. */
[hidden] { display: none !important; }

/* Honeypot. Lived in contact.css, which meant the "Website" trap field was
   plainly VISIBLE on the register form — the one place a bot signup actually
   costs you. Global now, so every form gets it.
   Positioned off-screen rather than display:none, which some bots detect. */
.hp {
  position: absolute !important; left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

/* --- Utilities -------------------------------------------------------- */
.u-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--s-4); top: -100px; z-index: var(--z-modal);
  background: var(--y-yellow); color: var(--y-black);
  padding: var(--s-3) var(--s-6); border-radius: var(--radius);
  font-weight: 600; transition: top var(--dur) var(--ease-out);
}
.skip-link:focus { top: var(--s-4); }

.container {
  width: 100%; max-width: var(--container);
  margin-inline: auto; padding-inline: var(--gutter);
}
.container--wide { max-width: var(--container-wide); }

.section { padding-block: var(--section-y); position: relative; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--accent-ink);
  margin: 0 0 var(--s-3);
}

.section__head { margin-bottom: var(--s-12); }
.section__title { max-width: 20ch; }
.section__sub { font-size: var(--fs-body-lg); color: var(--text-mid); max-width: 56ch; }

/* Accent — the one yellow word in a heading. Yellow as light, not as fill. */
.accent { color: var(--accent-ink); }

/* An alternating band. Two identical grounds in a row make a long page read as
   one undifferentiated scroll; this is the cheapest way to break it. */
.section--alt { background: var(--surface-1); border-block: 1px solid var(--surface-line); }
.section__foot { margin-top: var(--s-8); display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* --- Hero -------------------------------------------------------------
   Shared by every top-of-page hero on the site. Home and the business pages
   differ in content, not in shell. */
.hero {
  position: relative;
  padding-block: clamp(4rem, 2rem + 10vw, 9rem) clamp(3rem, 2rem + 5vw, 6rem);
  overflow: hidden;
}

/* Yellow as a LIGHT SOURCE, not as a fill. A soft radial bloom behind the
   headline reads premium; a flat yellow panel reads budget. */
.hero__glow {
  position: absolute; top: -30%; left: 50%;
  width: min(120vw, 1100px); aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 50%,
              color-mix(in srgb, var(--y-yellow) 26%, transparent) 0%,
              transparent 62%);
  pointer-events: none;
  will-change: transform;
}

.hero__inner { position: relative; }
.hero h1 { max-width: 18ch; margin-bottom: var(--s-6); }
.hero__sub {
  font-size: var(--fs-body-lg); color: var(--text-mid);
  max-width: 56ch; margin-bottom: var(--s-8);
}
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.hero__note { margin-top: var(--s-6); font-size: var(--fs-sm); color: var(--text-lo); }

/* Sub-pages sit under a breadcrumb and carry less air than the homepage. */
.hero--sub { padding-block: clamp(2.5rem, 1.5rem + 6vw, 5.5rem) clamp(2rem, 1.5rem + 4vw, 4rem); }

/* A hero's bottom padding and the next section's top padding stack, which on a
   wide screen adds up to ~10rem of dead space between a headline and the thing
   it introduces. The first section after a sub-hero collapses its own top
   padding — the hero has already provided the breathing room. */
.hero--sub + .section,
.hero--sub + .auth-wrap,
.hero--sub + section > .container > .legal { padding-top: var(--s-4); }
.hero--sub + .section--tight { padding-top: var(--s-2); }
.hero--sub h1 { max-width: 20ch; }
.hero__crumbs { margin-bottom: var(--s-6); }

/* Scaler's gradient sweep. Five stops is what makes the loop seamless. */
.sweep {
  background: linear-gradient(90deg,
    var(--y-yellow) 0%, var(--y-red) 25%, var(--y-yellow) 50%,
    var(--y-yellow-soft) 75%, var(--y-yellow) 100%);
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}

/* --- Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-6);
  border: 1px solid transparent; border-radius: var(--radius-pill);
  font-family: var(--font-body); font-size: var(--fs-body); font-weight: 600;
  line-height: 1; text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-spring),
              background-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.btn:active { transform: translateY(1px); }

/* A pill with `white-space: nowrap` and a long label is wider than a phone —
   "Pick a ready avatar from Ycotes Studio instead" measured 402px inside a
   390px viewport and put a horizontal scrollbar on the whole document. Buttons
   stay single-line wherever they fit; below that they are allowed to wrap and
   are capped at the container. Nothing changes on any screen where the label
   already fit. */
@media (max-width: 30rem) {
  .btn { white-space: normal; max-width: 100%; text-align: center; line-height: 1.25; }
}

/* Red is reserved for action. If it isn't a CTA, it isn't red. */
.btn--primary { background: var(--y-red); color: var(--y-white); }
.btn--primary:hover { background: var(--y-red-700); color: var(--y-white); box-shadow: var(--glow-red); }

.btn--secondary { background: var(--y-yellow); color: var(--y-black); }
.btn--secondary:hover { background: var(--y-yellow-300); color: var(--y-black); box-shadow: var(--glow-yellow); }

.btn--ghost { background: transparent; color: var(--text-hi); border-color: var(--surface-line); }
.btn--ghost:hover { border-color: var(--y-yellow); color: var(--accent-ink); background: var(--surface-1); }

.btn--sm { padding: var(--s-2) var(--s-4); font-size: var(--fs-sm); }
.btn--lg { padding: var(--s-4) var(--s-8); font-size: var(--fs-body-lg); }

/* --- Nav -------------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: var(--z-nav);
  background: color-mix(in srgb, var(--surface-0) 82%, transparent);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--surface-line);
}
.nav__inner {
  display: flex; align-items: center; gap: var(--s-6);
  min-height: 4.5rem;
}
.nav__brand {
  display: inline-flex; align-items: center; gap: var(--s-2);
  text-decoration: none; flex: 0 0 auto;
}
.nav__mark { border-radius: var(--radius-sm); }
.nav__wordmark {
  font-family: var(--font-display); font-size: 1.25rem; font-weight: 600;
  color: var(--text-hi); letter-spacing: -0.02em;
}

.door-switch {
  position: relative; display: none;
  padding: 3px; gap: 2px;
  background: var(--surface-1); border: 1px solid var(--surface-line);
  border-radius: var(--radius-pill);
}
.door-switch__btn {
  position: relative; z-index: 1;
  padding: var(--s-2) var(--s-4);
  background: none; border: 0; cursor: pointer; text-decoration: none;
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 600;
  color: var(--text-lo); border-radius: var(--radius-pill); white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.door-switch__btn:hover { color: var(--text-hi); }
.door-switch__btn[aria-current="page"] { color: var(--y-black); }
.door-switch__btn[aria-current="page"]:hover { color: var(--y-black); }
.door-switch__thumb {
  position: absolute; z-index: 0; top: 3px; bottom: 3px; left: 3px;
  width: calc(50% - 3px);
  background: var(--y-yellow); border-radius: var(--radius-pill);
  transition: transform var(--dur) var(--ease-out);
}
html[data-door="business"] .door-switch__thumb { transform: translateX(100%); }

.nav__links { display: none; margin-inline-start: auto; }
.nav__list { display: flex; gap: var(--s-6); align-items: center; }
.nav__list a {
  font-size: var(--fs-sm); font-weight: 500; color: var(--text-mid);
  text-decoration: none; position: relative; padding-block: var(--s-2);
}
.nav__list a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--y-yellow); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.nav__list a:hover { color: var(--text-hi); }
.nav__list a:hover::after { transform: scaleX(1); }

.nav__actions { display: none; gap: var(--s-2); margin-inline-start: var(--s-4); }

.nav__burger {
  margin-inline-start: auto;
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 0 10px;
  background: none; border: 0; cursor: pointer;
}
.nav__burger span {
  display: block; height: 2px; background: var(--text-hi); border-radius: 2px;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-fast) linear;
}

@media (min-width: 62rem) {
  .door-switch, .nav__links, .nav__actions { display: flex; }
  .nav__burger { display: none; }
}

/* --- Mobile menu ------------------------------------------------------ */
.mobile-menu {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: var(--surface-0);
  overflow-y: auto; overscroll-behavior: contain;
}
.mobile-menu[hidden] { display: none; }
.mobile-menu__top {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 4.5rem; border-bottom: 1px solid var(--surface-line);
}
.mobile-menu__close {
  width: 44px; height: 44px; font-size: 2rem; line-height: 1;
  background: none; border: 0; color: var(--text-hi); cursor: pointer;
}
.mobile-menu__body { padding-block: var(--s-8) var(--s-16); }
.mobile-menu__list { margin-bottom: var(--s-8); }
.mobile-menu__list a {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s-3) 0; border-bottom: 1px solid var(--surface-line);
  text-decoration: none;
}
.mobile-menu__list span { font-size: var(--fs-h3); color: var(--text-hi); font-family: var(--font-display); }
.mobile-menu__list small { font-size: var(--fs-sm); color: var(--text-lo); }
.mobile-menu__actions { display: flex; gap: var(--s-3); margin-top: var(--s-8); }
.mobile-menu__actions .btn { flex: 1; }

body.menu-open { overflow: hidden; }

/* --- Cards ------------------------------------------------------------ */
.card {
  background: var(--surface-1);
  border: 1px solid var(--surface-line);
  border-radius: var(--radius-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-card);
  transition: transform var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out);
}
.card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--y-yellow) 40%, var(--surface-line));
  box-shadow: var(--glow-yellow);
}
.card__title { font-size: var(--fs-h3); margin-bottom: var(--s-2); }
.card__body  { color: var(--text-mid); margin: 0; }
.card__link {
  display: inline-block; margin-top: var(--s-4);
  font-size: var(--fs-sm); font-weight: 600;
  color: var(--accent-ink); text-decoration: none;
}
.card__link:hover { text-decoration: underline; text-underline-offset: 0.25em; }

/* --- Grids. Deliberately several, so consecutive sections can differ. --- */
.grid { display: grid; gap: var(--s-6); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: repeat(2, 1fr); }
/* The 7/5 asymmetric split. Symmetry is what makes a two-up read as a
   comparison table rather than a designed layout. */
.grid--75 { grid-template-columns: 1fr; }

@media (min-width: 48rem) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
  .grid--75 { grid-template-columns: 7fr 5fr; gap: var(--s-12); }
}

/* --- Stats ------------------------------------------------------------ */
.stats { display: flex; flex-wrap: wrap; gap: var(--s-8) var(--s-12); }
.stat__num {
  font-family: var(--font-display); font-size: var(--fs-h2);
  color: var(--text-hi); line-height: 1; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat__label { font-size: var(--fs-sm); color: var(--text-lo); margin: var(--s-2) 0 0; }

/* --- Table (the capability inventory) --------------------------------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { width: 100%; border-collapse: collapse; min-width: 44rem; }
.table th, .table td {
  text-align: left; padding: var(--s-4);
  border-bottom: 1px solid var(--surface-line); font-size: var(--fs-sm);
}
.table th {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: var(--tracking-eyebrow); text-transform: uppercase;
  color: var(--text-lo); font-weight: 500;
}
.table td:first-child { color: var(--text-hi); font-weight: 600; }
.table tbody tr { transition: background-color var(--dur-fast) var(--ease-out); }
.table tbody tr:hover { background: var(--surface-1); }

/* --- Forms ------------------------------------------------------------ */
.input {
  width: 100%; padding: var(--s-3) var(--s-4);
  background: var(--surface-2); color: var(--text-hi);
  border: 1px solid var(--surface-line); border-radius: var(--radius);
  font-family: inherit; font-size: var(--fs-body);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.input::placeholder { color: var(--text-lo); }
.input:focus { border-color: var(--y-yellow); outline: none; }

/* --- Forms (shared: contact, login, register, newsletter) -------------- */
.form__row { margin-bottom: var(--s-5); }
/* auto-fit responds to the CONTAINER, not the viewport. A media query at 40rem
   never fired inside a 34rem card, so paired fields stayed stacked on a wide
   screen — the field pairing silently did nothing. */
.form__grid {
  display: grid; gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

.form__label {
  display: block; margin-bottom: var(--s-2);
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-hi);
}
.form__opt { font-weight: 400; color: var(--text-lo); }
.form__err { margin: var(--s-2) 0 0; font-size: var(--fs-sm); color: var(--y-red); }
.form__note { margin-top: var(--s-4); font-size: var(--fs-sm); color: var(--text-lo); }
.form__note a { color: var(--accent-ink); }

textarea.input { resize: vertical; min-height: 8rem; font-family: inherit; }
.input[aria-invalid="true"] { border-color: var(--y-red); }



/* --- Badges ----------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-1) var(--s-3);
  font-size: var(--fs-xs); font-weight: 600;
  border: 1px solid var(--surface-line); border-radius: var(--radius-pill);
  color: var(--text-mid); background: var(--surface-1);
}
.badge--demo { border-color: var(--y-yellow); color: var(--accent-ink); }

/* --- FAQ (every service page carries one) ----------------------------- */
.faq { max-width: 68ch; }
.faq__item { border-bottom: 1px solid var(--surface-line); }
/* Questions were set at --fs-h3 (up to 28px), so nearly every one wrapped onto
   a second line and each row ran ~90px tall — a list of eight became a page of
   its own. A question is a label, not a headline: one line each, and the
   answer underneath is where the reading actually happens. */
.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-4) 0; cursor: pointer;
  font-family: var(--font-display); font-size: var(--fs-body-lg);
  line-height: var(--lh-snug);
  color: var(--text-hi); list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "+"; font-family: var(--font-mono); font-size: 1.15rem;
  color: var(--accent-ink); flex: 0 0 auto;
  transition: transform var(--dur) var(--ease-out);
}
.faq__item[open] .faq__q::after { transform: rotate(45deg); }
.faq__a { padding-bottom: var(--s-4); }
.faq__a p { font-size: var(--fs-sm); line-height: var(--lh-body); }
.faq__a p { color: var(--text-mid); margin: 0 0 var(--s-3); }
.faq__a p:last-child { margin-bottom: 0; }

/* --- Closing band ----------------------------------------------------- */
.closing {
  position: relative; overflow: hidden;
  padding-block: clamp(4rem, 2rem + 9vw, 8rem);
  border-top: 1px solid var(--surface-line);
  text-align: center;
}
.closing__glow {
  position: absolute; bottom: -40%; left: 50%;
  width: min(120vw, 900px); aspect-ratio: 1; transform: translateX(-50%);
  background: radial-gradient(circle,
              color-mix(in srgb, var(--y-red) 20%, transparent) 0%, transparent 60%);
  pointer-events: none; will-change: transform;
}
.closing__inner { position: relative; }
.closing h2 { font-size: var(--fs-hero); max-width: 16ch; margin-inline: auto; }
.closing p { max-width: 52ch; margin-inline: auto; margin-bottom: var(--s-8);
             font-size: var(--fs-body-lg); }
.closing .hero__cta { justify-content: center; }

/* --- Breadcrumbs ------------------------------------------------------ */
.crumbs { display: flex; flex-wrap: wrap; gap: var(--s-2); font-size: var(--fs-sm); color: var(--text-lo); }
.crumbs a { text-decoration: none; }
.crumbs li + li::before { content: "/"; margin-inline-end: var(--s-2); color: var(--surface-line); }
.crumbs li { display: flex; }

/* --- Footer ----------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--surface-line);
  padding-block: var(--s-16) var(--s-8);
  background: var(--surface-1);
}
.footer__grid { display: grid; gap: var(--s-12); grid-template-columns: 1fr; }
@media (min-width: 48rem)  { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
/* Five columns since Company was added. The brand block keeps the widest
   share and contact keeps enough for an address that must not wrap mid-line. */
@media (min-width: 62rem)  { .footer__grid { grid-template-columns: 1.7fr 1fr 1fr 1fr 1.5fr; } }

.footer__pitch { color: var(--text-lo); font-size: var(--fs-sm); margin-top: var(--s-4); }
.footer__h { font-size: var(--fs-sm); font-family: var(--font-body); font-weight: 700;
             color: var(--text-hi); text-transform: uppercase;
             letter-spacing: var(--tracking-eyebrow); margin-bottom: var(--s-4); }
.footer__col ul li { margin-bottom: var(--s-2); }
.footer__col a { font-size: var(--fs-sm); color: var(--text-lo); text-decoration: none; }
.footer__col a:hover { color: var(--accent-ink); }

.footer__social { display: flex; flex-wrap: wrap; gap: var(--s-4); margin-top: var(--s-6); }
.footer__social a { font-size: var(--fs-sm); color: var(--text-mid); text-decoration: none; }

.footer__address { font-style: normal; font-size: var(--fs-sm); color: var(--text-lo); line-height: 1.7; }
.footer__contactlinks { margin-top: var(--s-3); }
.footer__contactlinks a { font-size: var(--fs-sm); color: var(--text-mid); text-decoration: none; }

.footer__news { margin-top: var(--s-6); }
.footer__newslabel { display: block; font-size: var(--fs-sm); color: var(--text-mid); margin-bottom: var(--s-2); }
.footer__newsrow { display: flex; gap: var(--s-2); }
.footer__newsnote { font-size: var(--fs-xs); color: var(--text-lo); margin-top: var(--s-2); }

.footer__bar {
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: center; justify-content: space-between;
  margin-top: var(--s-12); padding-top: var(--s-6);
  border-top: 1px solid var(--surface-line);
}
.footer__copy { font-size: var(--fs-sm); color: var(--text-lo); margin: 0; }
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-4); }
.footer__legal a { font-size: var(--fs-sm); color: var(--text-lo); text-decoration: none; }
.footer__disclaim {
  font-size: var(--fs-xs); color: var(--text-lo);
  margin-top: var(--s-6); max-width: 80ch; opacity: 0.8;
}

/* --- Theme toggle -------------------------------------------------------
   Both icons are in the DOM; CSS picks one from the theme class on <html>.
   That means the control is already correct at first paint — no JS needed to
   render it, only to change it. */
.theme-toggle {
  display: inline-grid; place-content: center;
  width: 40px; height: 40px; flex: 0 0 auto;
  background: transparent; color: var(--text-mid);
  border: 1px solid var(--surface-line); border-radius: var(--radius-pill);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-spring);
}
.theme-toggle:hover { color: var(--y-yellow); border-color: var(--y-yellow); }
.theme-toggle:active { transform: scale(0.94); }
.theme-toggle svg { grid-area: 1 / 1; transition: opacity var(--dur) var(--ease-out),
                                                  transform var(--dur) var(--ease-out); }

/* Dark theme -> offer the sun (switch to light). Light -> offer the moon. */
.theme-toggle__moon { opacity: 0; transform: rotate(-45deg) scale(0.6); }
.theme-toggle__sun  { opacity: 1; transform: none; }
.theme-light .theme-toggle__sun  { opacity: 0; transform: rotate(45deg) scale(0.6); }
.theme-light .theme-toggle__moon { opacity: 1; transform: none; }

/* The whole page cross-fades rather than snapping. Deliberately excludes
   transform so it never fights a GSAP tween mid-flight. */
.theme-anim, .theme-anim * {
  transition: background-color 240ms var(--ease-out),
              border-color 240ms var(--ease-out),
              color 240ms var(--ease-out) !important;
}

/* --- Hero artwork -------------------------------------------------------
   A framed panel beside the type, not a banner behind it. */
.hero__grid {
  display: grid; gap: var(--s-8); grid-template-columns: 1fr; align-items: center;
}
@media (min-width: 62rem) {
  /* 7/5 again. A 50/50 split makes the photo compete with the headline. */
  .hero__grid { grid-template-columns: 7fr 5fr; gap: var(--s-12); }
}
.hero__media {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  border: 1px solid var(--surface-line); box-shadow: var(--shadow-card);
  aspect-ratio: 4 / 3;
}
.hero__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A yellow wash ties stock photography to the brand instead of leaving it
   looking bought-in. Subtle: enough to unify, not enough to tint faces. */
.hero__media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(140deg,
              color-mix(in srgb, var(--y-yellow) 16%, transparent) 0%,
              transparent 45%,
              color-mix(in srgb, var(--y-red) 10%, transparent) 100%);
  mix-blend-mode: overlay;
}
@media (max-width: 61.99rem) { .hero__media { aspect-ratio: 16 / 9; } }

/* --------------------------------------------------------------------------
   Footer map.
   Lazy-loaded: the footer is below the fold on every page, so the embed is
   only fetched on views where someone scrolls to the bottom.
   -------------------------------------------------------------------------- */
.footer__map {
  position: relative;
  margin-top: var(--s-6);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--surface-line);
  background: var(--surface-2);
  aspect-ratio: 16 / 10;
  max-width: 22rem;
}
.footer__map iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ── THE BRAND LABEL OVER A MAP PIN ────────────────────────────────────────
   Shared by every embedded map on the site (footer, /about/#reach, /contact/),
   which is why it lives in site.css rather than in one page's stylesheet.

   Google's basic embed gives no way to label its marker — that needs the Embed
   API and a key, which is not worth introducing for one word. So the label is
   ours, painted over the iframe and anchored to the CENTRE of the box, which
   is exactly where Google drops its pin because every map here is centred on
   ORG_GEO.

   That equivalence is load-bearing: hand any of these embeds a text query
   again and Google re-centres on whatever it resolved, leaving this label
   pointing at the wrong roof.

   The 42px lift clears Google's marker, whose tip sits ON the centre point
   with a balloon rising ~30px above it. The marker is a fixed pixel size at
   every map size, so this one offset is correct on the 22rem footer map and
   the 34rem one on /about/ alike.

   The parent needs `position: relative` — .footer__map, .abMap and
   .contact__map all set it. */
.mapTag {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, calc(-100% - 42px));
  /* Never block dragging or zooming the map underneath. */
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: .3rem .6rem .3rem .4rem;
  border-radius: 999px;
  background: var(--y-yellow);
  color: var(--y-black);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .01em;
  line-height: 1.2;
  white-space: nowrap;
  /* A light chip on a light map needs a rim, not just a drop shadow. */
  box-shadow: 0 0 0 1.5px rgb(0 0 0 / .18), 0 6px 16px -4px rgb(0 0 0 / .45);
}

.mapTag img { display: block; border-radius: 4px; }

/* The tail that ties the chip to the pin underneath it. */
.mapTag::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--y-yellow);
}
.footer__maplink { margin: var(--s-3) 0 0; font-size: var(--fs-sm); }

/* --------------------------------------------------------------------------
   Signed-in user menu.

   Replaces "Log in / Join free" once a session exists — the bar was offering
   both to people who were already signed in, on the account page itself, which
   is the clearest possible way to tell somebody their login did not stick.
   -------------------------------------------------------------------------- */
.usermenu { position: relative; }

.usermenu__btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-1) var(--s-3) var(--s-1) var(--s-1);
  border-radius: var(--radius-pill);
  border: 1px solid var(--surface-line);
  background: var(--surface-1);
  color: var(--text-hi);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.usermenu__btn:hover { border-color: rgb(240 198 74 / 0.5); background: var(--surface-2); }

.usermenu__pic {
  width: 2rem; height: 2rem; border-radius: 50%;
  object-fit: cover; display: grid; place-items: center; flex: none;
}
.usermenu__pic--ini {
  background: var(--y-yellow); color: var(--y-black);
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.02em;
}
.usermenu__name { font-size: var(--fs-sm); font-weight: 500; }
.usermenu__caret { color: var(--text-lo); transition: transform var(--dur) var(--ease-out); }
.usermenu__btn[aria-expanded="true"] .usermenu__caret { transform: rotate(180deg); }

.usermenu__panel {
  position: absolute; right: 0; top: calc(100% + var(--s-2));
  z-index: var(--z-dropdown);
  min-width: 15rem;
  padding: var(--s-3);
  border-radius: var(--radius);
  border: 1px solid var(--surface-line);
  background: var(--surface-1);
  box-shadow: var(--shadow-card);
  display: grid; gap: 2px;
}
/* On the light theme --surface-1 is pure white and the page is #FFFDF7, so the
   panel was white-on-white behind a hairline border — open, correctly sized,
   and completely invisible. A dropdown has to read as a layer ABOVE the page,
   which on a light ground means a real shadow, not a 1px line. */
.theme-light .usermenu__panel {
  border-color: rgb(28 28 28 / 0.10);
  box-shadow: 0 1px 2px rgb(28 28 28 / 0.06),
              0 12px 28px -8px rgb(28 28 28 / 0.18),
              0 32px 64px -24px rgb(28 28 28 / 0.22);
}
/* [hidden] loses to `display: grid` on specificity, the same trap that once
   left both nav menus visible at the same time. */
.usermenu__panel[hidden] { display: none; }

.usermenu__who {
  display: grid; gap: 2px; margin: 0;
  padding: var(--s-2) var(--s-3) var(--s-3);
  border-bottom: 1px solid var(--surface-line);
  margin-bottom: var(--s-2);
  max-width: none;
}
.usermenu__who strong { color: var(--text-hi); font-size: var(--fs-sm); }
.usermenu__who span { color: var(--text-lo); font-size: var(--fs-xs); overflow-wrap: anywhere; }

.usermenu__panel a,
.usermenu__out {
  display: block; width: 100%; text-align: left;
  padding: var(--s-2) var(--s-3);
  border: 0; background: none; cursor: pointer;
  border-radius: var(--radius-sm);
  color: var(--text-mid); font-size: var(--fs-sm); text-decoration: none;
  font: inherit; font-size: var(--fs-sm);
}
.usermenu__panel a:hover,
.usermenu__out:hover { background: var(--surface-2); color: var(--text-hi); }
.usermenu__out { color: var(--y-red); margin-top: var(--s-2); border-top: 1px solid var(--surface-line); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }

@media (max-width: 60rem) { .usermenu { display: none; } }

/* --------------------------------------------------------------------------
   Mobile menu profile card.
   The desktop bar gets a dropdown; on a phone the menu IS the dropdown, so the
   identity belongs at the top of the sheet rather than as two buttons at the
   bottom of it.
   -------------------------------------------------------------------------- */
.mprofile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  margin-bottom: var(--s-4);
  border-radius: var(--radius);
  border: 1px solid var(--surface-line);
  background: linear-gradient(140deg, rgb(240 198 74 / 0.10), var(--surface-1));
  text-decoration: none;
  transition: border-color var(--dur) var(--ease-out);
}
.mprofile:hover { border-color: rgb(240 198 74 / 0.5); }

.mprofile__pic {
  width: 3.25rem; height: 3.25rem; border-radius: 50%;
  object-fit: cover; display: grid; place-items: center; flex: none;
}
.mprofile__pic--ini {
  background: var(--y-yellow); color: var(--y-black);
  font-weight: 600; font-size: var(--fs-body);
}
.mprofile__text { display: grid; gap: 2px; min-width: 0; }
.mprofile__text strong { color: var(--text-hi); font-size: var(--fs-body-lg); }
.mprofile__text span {
  color: var(--text-lo); font-size: var(--fs-sm);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mprofile__go { color: var(--y-yellow); flex: none; }
.mprofile__links { margin-bottom: var(--s-4); }

/* ══════════════════════════════════════════════════════════════════════════
   GLOBAL SEARCH — command palette
   Lives in site.css because it is on every page; a separate stylesheet would
   be a second request on every page for ~90 lines.
   ══════════════════════════════════════════════════════════════════════════ */
.ycs {
  position: fixed; inset: 0; z-index: 200;
  display: grid; align-items: start; justify-items: center;
  padding: clamp(var(--s-8), 12vh, var(--s-32)) var(--gutter) var(--s-8);
  background: rgb(8 8 10 / .72);
  backdrop-filter: blur(6px);
}
.ycs[hidden] { display: none; }

.ycs__panel {
  width: min(40rem, 100%);
  border-radius: var(--radius-lg);
  border: 1px solid var(--surface-line);
  background: var(--surface-1);
  box-shadow: 0 40px 90px -30px rgb(0 0 0 / .9);
  overflow: hidden;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: min(32rem, 70vh);
}

.ycs__bar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--surface-line);
}
.ycs__bar svg { width: 1.1rem; height: 1.1rem; color: var(--text-lo); flex: none; }
.ycs__in {
  flex: 1; min-width: 0;
  border: 0; background: none; padding: 0;
  font: inherit; font-size: var(--fs-body-lg); color: var(--text-hi);
}
.ycs__in:focus { outline: none; }
.ycs__in::placeholder { color: var(--text-lo); }
.ycs__esc {
  flex: none; border: 0; padding: .2rem .5rem; cursor: pointer;
  border-radius: 5px; background: var(--surface-2);
  font-family: var(--font-mono); font-size: .62rem; color: var(--text-lo);
}

.ycs__res { overflow-y: auto; padding: var(--s-2); }
.ycsGroup {
  margin: var(--s-3) var(--s-3) var(--s-1);
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-lo);
}
.ycsHit {
  display: grid; gap: .1rem;
  padding: .6rem var(--s-3); border-radius: var(--radius);
  text-decoration: none;
  /* No transition on the highlight. The selection follows the arrow keys and
     a fade makes held-down navigation look like it is lagging behind. */
}
.ycsHit.is-on { background: var(--surface-2); }
.ycsHit__t { font-size: var(--fs-sm); font-weight: 600; color: var(--text-hi); }
.ycsHit__m {
  font-size: var(--fs-xs); color: var(--text-lo);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ycsHit.is-on .ycsHit__m { color: var(--text-mid); }

.ycs__foot {
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--surface-line);
  font-size: var(--fs-xs); color: var(--text-lo);
}

/* The nav trigger. Hidden on phones — a 44px target for a feature whose whole
   point is a keyboard shortcut is not worth the width on a 390px screen. */
.navSearch {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: .4rem .7rem; border-radius: var(--radius-pill);
  border: 1px solid var(--surface-line); background: var(--surface-1);
  cursor: pointer; font: inherit; font-size: var(--fs-xs); color: var(--text-lo);
  transition: border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}
.navSearch:hover { border-color: var(--y-yellow); color: var(--text-hi); }
.navSearch svg { width: .9rem; height: .9rem; }
.navSearch kbd {
  padding: .05rem .3rem; border-radius: 4px;
  background: var(--surface-2); border: 1px solid var(--surface-line);
  font-family: var(--font-mono); font-size: .58rem;
}
@media (max-width: 62rem) { .navSearch { display: none; } }

/* ── search inside the mobile sheet ────────────────────────────────────────
   .navSearch is hidden below 62rem because a ⌘K hint means nothing on a
   phone. The SEARCH still does, so the sheet carries its own full-width
   trigger — without it the feature was unreachable on the device most of this
   audience uses. */
.msearch {
  display: flex; align-items: center; gap: var(--s-3); width: 100%;
  margin-bottom: var(--s-6); padding: var(--s-4);
  border-radius: var(--radius); border: 1px solid var(--surface-line);
  background: var(--surface-1); cursor: pointer;
  font: inherit; font-size: var(--fs-body); color: var(--text-lo);
  text-align: left;
}
.msearch:hover, .msearch:focus-visible { border-color: var(--y-yellow); color: var(--text-hi); }
.msearch svg { flex: none; width: 1.1rem; height: 1.1rem; }

/* ── search in the mobile bar ──────────────────────────────────────────────
   Sits beside the burger, visible without opening anything. Hidden at desktop,
   where .navSearch already shows the labelled control with its ⌘K hint. */
.nav__search {
  display: none;
  align-items: center; justify-content: center;
  width: 2.6rem; height: 2.6rem; flex: none;
  border-radius: 50%; border: 1px solid var(--surface-line);
  background: var(--surface-1); color: var(--text-mid); cursor: pointer;
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.nav__search svg { width: 1.15rem; height: 1.15rem; }
.nav__search:hover, .nav__search:focus-visible { color: var(--text-hi); border-color: var(--y-yellow); }
@media (max-width: 62rem) { .nav__search { display: inline-flex; } }

/* ══════════════════════════════════════════════════════════════════════════
   AUDIENCE BANDS — the line between the two halves of the company
   ══════════════════════════════════════════════════════════════════════════ */
.audband {
  position: relative;
  padding: clamp(var(--s-6), 3.5vh, var(--s-10)) var(--gutter) 0;
}

/* The dead space ABOVE the rule was never the band's — it is the preceding
   section's own bottom padding, which is sized for a gap between two full
   sections, not for a divider that belongs to the one below it. Scoped with
   :has() so only the section immediately before a band is tightened, and every
   other section on the site keeps its normal rhythm. */
section:has(+ .audband) { padding-bottom: clamp(var(--s-8), 4vh, var(--s-12)); }

/* Likewise below: the band and the section under it are ONE unit, so the
   section does not need its full opening padding as well. */
.audband + section { padding-top: var(--s-6); }
.audband__in { width: min(var(--container), 100%); margin-inline: auto; }

/* A rule above the label, so the band reads as a divider and not as another
   section heading competing with the one below it. */
.audband__in::before {
  content: ''; display: block; width: 100%; height: 1px; margin-bottom: var(--s-5);
  background: linear-gradient(90deg, var(--h-col), transparent 70%);
}
.audband--stu { --h-col: rgb(240 198 74 / .6); }
.audband--biz { --h-col: rgb(232 84 74 / .6); }

.audband__k {
  display: inline-block; margin: 0 0 var(--s-4);
  padding: .3rem .9rem; border-radius: var(--radius-pill);
  border: 1px solid var(--h-col);
  background: color-mix(in srgb, var(--h-col) 12%, transparent);
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-hi);
}
.audband__h {
  margin: 0 0 var(--s-3); max-width: 20ch;
  font-family: var(--font-display); font-size: clamp(2rem, 5.5vw, 3.6rem);
  line-height: 1.02; letter-spacing: -.035em; color: var(--text-hi);
}
.audband__p {
  margin: 0; max-width: 54ch;
  font-size: var(--fs-body-lg); line-height: var(--lh-body); color: var(--text-lo);
}

@media (max-width: 46rem) {
  .audband { padding-top: var(--s-6); }
  .audband__h { font-size: clamp(1.7rem, 8vw, 2.4rem); }
}

/* A label-only band. Without this it keeps the full band's bottom padding and
   leaves a screen of empty space between the chip and the section under it. */
.audband--label { padding-bottom: 0; }
.audband--label .audband__k { margin-bottom: 0; }
