/* ==========================================================================
   Firette — firette.com
   Palette derived from Logo/firette-logo.svg. Mobile first; one breakpoint
   at 860px where the navigation expands to a horizontal bar.
   ========================================================================== */

:root {
  --teal:       #3ab7a8;
  --teal-dark:  #1e8a7e;
  --teal-deep:  #14655c;
  --flame:      #f4a261;
  --flame-dark: #d9822b;
  --ink:        #333333;
  --grey:       #666666;
  --grey-light: #7d7d7d;
  --paper:      #ffffff;
  --mist:       #f6f8f8;
  --line:       #e2e8e8;
  --charcoal:   #2b3333;

  --wrap: 1120px;
  --gap: 1.5rem;
  --radius: 6px;
  --shadow: 0 2px 4px rgba(20, 40, 40, .06), 0 12px 28px rgba(20, 40, 40, .07);
  --shadow-sm: 0 1px 3px rgba(20, 40, 40, .1);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, "Noto Sans", sans-serif;
}

/* --------------------------------------------------------------- reset -- */

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

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: clamp(1rem, .97rem + .15vw, 1.0625rem);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  overflow-x: hidden;
}

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

h1, h2, h3 { line-height: 1.2; color: var(--charcoal); font-weight: 600; margin: 0 0 .6em; }
h1 { font-size: clamp(1.85rem, 1.4rem + 2vw, 2.85rem); }
h2 { font-size: clamp(1.4rem, 1.2rem + 1vw, 1.9rem); }
h3 { font-size: clamp(1.1rem, 1rem + .4vw, 1.3rem); }

p, ul, ol { margin: 0 0 1.15em; }

a { color: var(--teal-dark); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--teal-deep); }

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

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--charcoal); color: #fff; padding: .75rem 1.25rem;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }

/* -------------------------------------------------------------- header -- */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
  border-bottom: 3px solid var(--teal);
  box-shadow: var(--shadow-sm);
}

.header-inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  min-height: 74px;
  padding-block: .75rem;
}

.brand { margin-right: auto; display: inline-flex; }
.brand img { width: 190px; height: auto; }

.nav-toggle {
  display: inline-flex; align-items: center; gap: .5rem;
  font: inherit; font-weight: 600; color: var(--charcoal);
  background: var(--mist); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .55rem .9rem; cursor: pointer;
}
.nav-toggle:hover { background: #eef3f3; }

.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block; width: 18px; height: 2px; background: var(--charcoal);
  content: ""; position: relative;
}
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after  { top: 4px; }

.site-nav { display: none; flex-basis: 100%; }
.site-nav.is-open { display: block; }

.nav-list { list-style: none; margin: 0; padding: .5rem 0 0; }

.nav-item { position: relative; border-top: 1px solid var(--line); }

.nav-link {
  display: block; padding: .85rem .25rem;
  color: var(--charcoal); text-decoration: none; font-weight: 600;
}
.nav-item.is-current > .nav-link { color: var(--teal-dark); }

.submenu-toggle {
  position: absolute; right: 0; top: 0;
  width: 3rem; height: 3.1rem;
  background: none; border: 0; cursor: pointer;
  color: var(--grey); font-size: 1rem;
}
.submenu-toggle[aria-expanded="true"] { transform: rotate(180deg); }

.submenu {
  list-style: none; margin: 0; padding: 0 0 .5rem .9rem;
  display: none;
  border-left: 3px solid var(--flame);
}
.submenu.is-open { display: block; }
.submenu a {
  display: block; padding: .5rem .25rem;
  color: var(--grey); text-decoration: none; font-size: .95rem;
}
.submenu a:hover, .submenu a[aria-current="page"] { color: var(--teal-dark); }

@media (min-width: 860px) {
  .nav-toggle { display: none; }
  .site-nav { display: block; flex-basis: auto; }
  .nav-list { display: flex; gap: .25rem; padding: 0; }
  .nav-item { border-top: 0; }
  .nav-link {
    padding: .6rem .8rem; border-radius: var(--radius);
    border-bottom: 3px solid transparent;
  }
  .nav-item:hover > .nav-link { color: var(--teal-dark); }
  .nav-item.is-current > .nav-link { border-bottom-color: var(--flame); }

  .nav-item.has-children > .nav-link { padding-right: 1.6rem; }
  .submenu-toggle {
    width: 1.5rem; height: 100%; right: .2rem;
    pointer-events: none;                 /* hover opens it on desktop */
  }

  .submenu {
    display: block; visibility: hidden; opacity: 0;
    position: absolute; top: 100%; left: 0; z-index: 110;
    min-width: 17rem; padding: .4rem 0;
    background: var(--paper);
    border: 1px solid var(--line);
    border-top: 3px solid var(--flame);
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: var(--shadow);
    transition: opacity .15s ease;
  }
  .nav-item.has-children:hover > .submenu,
  .nav-item.has-children:focus-within > .submenu,
  .submenu.is-open { visibility: visible; opacity: 1; }
  .submenu a { padding: .6rem 1rem; }
  .submenu a:hover { background: var(--mist); }
}

/* ------------------------------------------------------------ carousel -- */

/* How the photograph sits in the frame. These two properties are the whole
   switch — change nothing else to move between the modes:
     contain + the teal gradient   whole photograph visible, brand colour fills the gaps
     cover   + var(--charcoal)     photograph fills the frame, edges cropped (original)

   They are declared on .hero rather than .carousel because custom properties
   inherit downwards only — .hero is the ancestor, so a value set on .carousel
   would never reach it.

   The backdrop runs light at both edges and deep through the middle, so the
   band level with the photograph is darkest and the photograph reads as sitting
   on top of it rather than floating in flat colour. Photographs in the pool run
   from 4:3 to wider than 16:9, so the visible area of backdrop changes from
   slide to slide. */
.hero {
  --carousel-fit: contain;

  /* The end stops are chosen to meet the neighbouring sections exactly, so the
     carousel has no visible seam top or bottom:
       top    var(--teal)       matches .site-header's 3px teal bottom border
       bottom var(--teal-dark)  matches .hero-intro, whose 135deg gradient
                                starts at --teal-dark along its top edge
     The middle is --teal-deep so the band level with the photograph recedes. */
  --carousel-backdrop: linear-gradient(
      to bottom,
      var(--teal) 0%,
      var(--teal-deep) 50%,
      var(--teal-dark) 100%);

  /* No legibility wash in `contain` mode — it would darken the very edges the
     stops above exist to match. For `cover` mode restore:
       linear-gradient(to top, rgba(12,20,20,.92) 0%, rgba(12,20,20,.72) 22%,
                               rgba(12,20,20,.28) 48%, rgba(12,20,20,.04) 72%) */
  --carousel-scrim: none;

  background: var(--carousel-backdrop);
}

.carousel {
  position: relative;
  height: clamp(320px, 58vh, 620px);
  overflow: hidden;
  background: var(--carousel-backdrop, var(--charcoal));
}

/* Two stacked layers cross-fade; the active one sits on top. Images are real
   <img> elements (not CSS backgrounds) so no inline style is needed — the CSP
   forbids inline styles. */
/* Hovering the hero pauses the carousel. Without a cue that reads as a
   deliberate pause rather than a stall, a resting pointer looks like a broken
   slideshow. The class is added only while the pointer is over a carousel that
   would otherwise be advancing; removing it restores the inherited cursor, so
   the buttons keep their own `pointer` either way. */
.carousel.is-hover-paused {
  cursor: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'><circle cx='16' cy='16' r='13' fill='rgba(15,25,25,0.55)' stroke='white' stroke-width='2'/><rect x='11' y='10' width='4' height='12' rx='1' fill='white'/><rect x='17' y='10' width='4' height='12' rx='1' fill='white'/></svg>") 16 16, default;
}

.carousel-slide {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .8s ease;
}
.carousel-slide.is-active { opacity: 1; }

/* Reduced motion removes the animation, not the feature: the carousel still
   starts paused (carousel.js), but a visitor who presses play gets instant
   swaps rather than no carousel at all. */
@media (prefers-reduced-motion: reduce) {
  .carousel-slide { transition: none; }
}
.carousel-slide img {
  width: 100%; height: 100%;
  object-fit: var(--carousel-fit); object-position: center;
}

/* Legibility wash for the city name, driven by --carousel-scrim on .hero. It
   is `none` while the backdrop gradient is on show, because any darkening here
   lands on the frame edges and breaks the seam with the sections above and
   below. The element stays in the markup so restoring it is a one-value
   change. The city name relies on its text-shadow instead. */
.carousel-scrim {
  position: absolute; inset: 0;
  background: var(--carousel-scrim, none);
}

.carousel-caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.5rem 0 1.75rem;
  color: #fff;
}
.carousel-city {
  margin: 0;
  /* Explicit: the generic h2 rule would otherwise paint this charcoal. */
  color: #fff;
  font-size: clamp(1.8rem, 1.2rem + 3vw, 3.25rem);
  font-weight: 600;
  letter-spacing: .01em;
  /* Carries more of the legibility load now the scrim is lighter: a tight dark
     halo for edge definition, a wider soft one for light backgrounds. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, .7), 0 2px 16px rgba(0, 0, 0, .6);
}
.carousel-city::after {
  content: ""; display: block; width: 3.5rem; height: 4px;
  background: var(--flame); margin-top: .55rem;
}

.carousel-controls {
  position: absolute; right: 1rem; bottom: 1.15rem;
  display: flex; gap: .4rem; z-index: 3;
}
.carousel-btn {
  width: 2.6rem; height: 2.6rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(15, 25, 25, .5);
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 50%;
  color: #fff; font-size: 1rem; cursor: pointer;
}
.carousel-btn:hover { background: var(--teal-dark); border-color: var(--teal-dark); }

/* On narrow screens the controls would sit on top of the credit line. */
@media (max-width: 619px) {
  .carousel-controls { top: .9rem; bottom: auto; }
}

/* ---------------------------------------------------- scroll cue -- */

/* "More below" hint on the front page. On desktop the What-we-do section can sit
   just under the fold behind the carousel + intro band; this floats a down-arrow
   at the bottom-centre of the viewport while that section is off-screen.
   Visibility is split the same way as the nav: JS (scrollcue.js) toggles
   `.is-shown` based on whether #what-we-do is in view, and CSS owns the
   breakpoint — the arrow can only ever appear at >= 860px. It shares the
   carousel buttons' visual language so it reads as part of the hero. */
.scroll-cue {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 50;                     /* above content, below the sticky header (100) */
  width: 2.6rem; height: 2.6rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(15, 25, 25, .5);
  border: 1px solid rgba(255, 255, 255, .35);
  border-radius: 50%;
  /* Hidden and out of the tab order until revealed; opacity carries the fade. */
  opacity: 0; visibility: hidden;
  transition: opacity .4s ease, visibility .4s;
}
.scroll-cue:hover { background: var(--teal-dark); border-color: var(--teal-dark); }

/* CSS chevron: a small box showing only its lower-right edges, rotated 45deg to
   point down. Nudged up 2px so it sits optically centred in the circle. */
.scroll-cue-arrow {
  width: .7rem; height: .7rem;
  margin-top: -2px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg);
}

/* Reveal only on desktop, and only when JS says the section is out of view. */
@media (min-width: 860px) {
  .scroll-cue.is-shown { opacity: 1; visibility: visible; }
}
/* Belt-and-braces: never render on phones even if the class is present. */
@media (max-width: 859px) {
  .scroll-cue { display: none; }
}
/* Gentle bob to catch the eye; stilled for reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .scroll-cue.is-shown .scroll-cue-arrow { animation: scroll-cue-bob 1.8s ease-in-out infinite; }
}
@keyframes scroll-cue-bob {
  0%, 100% { transform: translateY(-2px) rotate(45deg); }
  50%      { transform: translateY(2px) rotate(45deg); }
}

/* Same treatment as the carousel above: light at the edges, deep through the
   middle, running vertically. It was a 135deg diagonal, which put the dark
   corner at the right and meant the top edge drifted from --teal-dark to
   --teal-deep across the width — so the seam with the carousel above was clean
   on the left and stepped on the right. A vertical gradient holds --teal-dark
   right across the top edge, which is exactly what the carousel's bottom stop
   meets. */
.hero-intro {
  background: linear-gradient(
      to bottom,
      var(--teal-dark) 0%,
      var(--teal-deep) 50%,
      var(--teal-dark) 100%);
  color: #fff;
  padding-block: 2.5rem;
}
.hero-intro h1 { color: #fff; margin-bottom: .35em; }
.hero-intro p { margin: 0; max-width: 62ch; color: rgba(255, 255, 255, .93); font-size: 1.1rem; }

/* --------------------------------------------------------------- pages -- */

.page-hero {
  background: var(--mist);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(2rem, 1rem + 4vw, 3.5rem);
}
.page-hero h1 { margin-bottom: .3em; }
.page-hero .lede { font-size: 1.15rem; color: var(--grey); max-width: 65ch; margin: 0; }

.eyebrow {
  display: inline-block;
  font-size: .78rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--teal-dark);
  margin-bottom: .6rem;
}

section.band { padding-block: clamp(2.25rem, 1.5rem + 3vw, 4rem); }
section.band.alt { background: var(--mist); border-block: 1px solid var(--line); }

.prose { max-width: 68ch; }
.prose h2 { margin-top: 1.8em; }
.prose h2:first-child { margin-top: 0; }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: .4em; }
.prose strong { color: var(--charcoal); }

.layout-aside {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3rem);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .layout-aside { grid-template-columns: minmax(0, 1fr) 20rem; align-items: start; }
}

.sidebar {
  background: var(--mist);
  border-top: 4px solid var(--teal);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.sidebar h2 { font-size: 1.15rem; }
.sidebar h2 + p, .sidebar h2 + ul { margin-top: 0; }
.sidebar ul + h2, .sidebar p + h2 { margin-top: 1.6rem; }
.sidebar ul { list-style: none; padding: 0; margin: 0; }
.sidebar li { padding: .4rem 0; border-bottom: 1px solid var(--line); }
.sidebar li:last-child { border-bottom: 0; }

/* --------------------------------------------------------------- cards -- */

.card-grid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 4px solid var(--teal);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column;
}
.card h2, .card h3 { font-size: 1.2rem; margin-bottom: .5rem; }
.card p { color: var(--grey); }
.card ul { list-style: none; padding: 0; margin: 0 0 1rem; }
.card li { padding: .3rem 0 .3rem 1.2rem; position: relative; color: var(--grey); }
.card li::before {
  content: ""; position: absolute; left: 0; top: .85em;
  width: .45rem; height: .45rem; background: var(--flame); border-radius: 50%;
}
.card .card-link { margin-top: auto; font-weight: 600; text-decoration: none; }
.card .card-link::after { content: " \2192"; }
.card.flame { border-top-color: var(--flame); }

/* ------------------------------------------------------------ elements -- */

.btn {
  display: inline-block;
  padding: .8rem 1.6rem;
  background: var(--teal-dark); color: #fff;
  border: 2px solid var(--teal-dark); border-radius: var(--radius);
  font-weight: 600; text-decoration: none; cursor: pointer;
  font-family: inherit; font-size: 1rem;
}
.btn:hover { background: var(--teal-deep); border-color: var(--teal-deep); color: #fff; }
.btn.ghost { background: transparent; color: var(--teal-dark); }
.btn.ghost:hover { background: var(--teal-dark); color: #fff; }
.btn.flame { background: var(--flame-dark); border-color: var(--flame-dark); }
.btn.flame:hover { background: #bf6f1f; border-color: #bf6f1f; }
.btn[disabled] { opacity: .6; cursor: not-allowed; }

.pull-quote {
  border-left: 4px solid var(--flame);
  background: var(--mist);
  padding: 1rem 1.25rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 1.75rem 0;
}
.pull-quote p:last-child { margin-bottom: 0; }

.cta-band {
  background: linear-gradient(135deg, var(--teal-dark), var(--teal-deep));
  color: #fff;
  padding-block: clamp(2rem, 1.5rem + 2vw, 3rem);
}
.cta-band h2 { color: #fff; }
.cta-band p { color: rgba(255, 255, 255, .92); max-width: 58ch; }
.cta-band .btn { background: #fff; color: var(--teal-deep); border-color: #fff; }
.cta-band .btn:hover { background: var(--flame); border-color: var(--flame); color: var(--charcoal); }

/* ---------------------------------------------------------------- form -- */

.form-card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 4px solid var(--teal);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  box-shadow: var(--shadow-sm);
}

.field { margin-bottom: 1.1rem; }
.field label { display: block; font-weight: 600; margin-bottom: .35rem; color: var(--charcoal); }
.field .req { color: var(--flame-dark); }
.field input, .field textarea {
  width: 100%;
  font: inherit; color: var(--ink);
  padding: .7rem .85rem;
  border: 1px solid #c8d2d2; border-radius: var(--radius);
  background: var(--paper);
}
.field input:focus, .field textarea:focus { border-color: var(--teal); }
.field textarea { resize: vertical; min-height: 9rem; }
.field-row { display: grid; gap: 0 1rem; grid-template-columns: 1fr; }
@media (min-width: 620px) { .field-row { grid-template-columns: 1fr 1fr; } }

/* Honeypot — must stay reachable to bots but invisible to people. */
.honeypot-field {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

.form-feedback {
  margin-top: 1rem; padding: .85rem 1rem;
  border-radius: var(--radius); display: none;
}
.form-feedback.is-visible { display: block; }
.form-feedback.ok    { background: #e6f5f2; border: 1px solid var(--teal); color: var(--teal-deep); }
.form-feedback.error { background: #fdeee2; border: 1px solid var(--flame-dark); color: #8a4a10; }

.form-note { font-size: .85rem; color: var(--grey-light); }

/* Send diagnostics, shown only when config debug_mail is on (see contact.js). */
.form-debug[hidden] { display: none; }
.form-debug {
  margin-top: 1rem; padding: .85rem 1rem;
  background: var(--mist); border: 1px solid var(--line); border-radius: var(--radius);
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: .8rem; line-height: 1.5; color: var(--ink);
  white-space: pre-wrap; word-break: break-word;
  max-height: 22rem; overflow: auto;
}

/* ------------------------------------------------------------- credits -- */

.credit-city { margin-bottom: 2rem; }
.credit-city h2 { font-size: 1.2rem; margin-bottom: .4rem; }
.credit-list { list-style: none; padding: 0; margin: 0; font-size: .9rem; color: var(--grey); }
.credit-list li { padding: .3rem 0; border-bottom: 1px solid var(--line); }

/* -------------------------------------------------------------- footer -- */

.site-footer {
  background: var(--charcoal);
  color: #cfd8d8;
  padding-top: clamp(2rem, 1.5rem + 2vw, 3rem);
  margin-top: 0;
}
.footer-grid {
  display: grid; gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  padding-bottom: 2rem;
}
.footer-logo { width: 180px; }
.footer-tag { color: #9fb0b0; font-size: .95rem; max-width: 24ch; margin-top: 1rem; }
.footer-col h2 {
  font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--teal); margin-bottom: .8rem;
}
.footer-col ul { list-style: none; padding: 0; margin: 0 0 1rem; }
.footer-col li { padding: .22rem 0; }
.footer-col a, .footer-contact a { color: #cfd8d8; text-decoration: none; font-size: .93rem; }
.footer-col a:hover, .footer-contact a:hover { color: var(--flame); text-decoration: underline; }
/* The two market headings link to their overview pages — keep them looking like
   headings, not like the list of links beneath them. */
.footer-col h2 a { color: inherit; font-size: inherit; letter-spacing: inherit; }
.footer-contact { font-size: .93rem; }
.footer-contact a { color: var(--teal); }

.footer-legal {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding-block: 1.1rem;
  display: flex; flex-wrap: wrap; gap: .3rem 2rem; justify-content: space-between;
}
.footer-legal p { margin: 0; font-size: .82rem; color: #8fa0a0; }
.footer-legal a { color: #8fa0a0; }

.footer-legal-links {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .3rem 1.25rem;
  font-size: .82rem;
}
.footer-legal-links a { color: #8fa0a0; }

/* ------------------------------------------------------ policy pages -- */

.policy-meta { color: var(--grey); font-size: .9rem; }
.prose h3 { margin-top: 1.4em; font-size: 1.05rem; }

/* The cookie table is the one place on the site with tabular data. It must be
   able to scroll on its own rather than widening the page. */
.table-scroll { overflow-x: auto; margin: 1.5rem 0; }
.policy-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: .92rem;
  text-align: left;
}
.policy-table th, .policy-table td {
  border-bottom: 1px solid var(--line);
  padding: .65rem .8rem;
  vertical-align: top;
}
.policy-table thead th {
  border-bottom-width: 2px;
  color: var(--charcoal);
  font-size: .8rem; letter-spacing: .06em; text-transform: uppercase;
}
.policy-table code {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: .9em;
  background: var(--mist);
  padding: .1em .35em;
  border-radius: 3px;
}

/* ---------------------------------------------------------- utilities -- */

.stack > * + * { margin-top: 1rem; }
.center { text-align: center; }
.mt-2 { margin-top: 2rem; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
