/* ==========================================================================
   ENGAGE.UG - STYLESHEET
   ==========================================================================
   One plain stylesheet for the whole site. No framework.
   CONTENTS
     1. Fonts
     2. Design tokens (CSS variables)
     3. Reset and base
     4. Layout        .container .stack .cluster .grid .split
     5. Components    .btn .site-nav .page .panel .info-card .feature
                      .card .badge .table .field/.input .carousel
                      .sponsor-tile/-tier .tooltip [data-tip]
                      .site-footer .consent .dialog
     6. Utilities
     7. Sessions, agenda and speakers, info pages, dialog content
   RULES
     - Colours, spacing, radii, shadows, fonts and z-indexes come from the
       variables in section 2. A raw colour value is written only there.
     - Mobile first: base rules are for small screens, wider screens are added
       with @media (min-width: ...), never max-width.
         md = 48em (768px)   lg = 62em (992px)
       (CSS can't use variables inside media queries, so the numbers are
       repeated in the file. A few carousel steps use 22.5em, 37.5em, 56em,
       69em, 81em, the widths where the number of logos changes.)
     - Flat selectors: one class, optionally with a state or a modifier.
       No IDs, and no !important except [hidden].
     - Naming: .block, .block__element, .block--modifier.
     - Behaviour in JavaScript is attached to data-* attributes (data-dialog,
       data-carousel, data-tip, ...), never to classes, so renaming a class
       can't break a script.
   ========================================================================== */
/* ==========================================================================
   1. FONTS
   Jost and Montserrat (variable, all weights) come from Google Fonts and
   Font Awesome from jsDelivr; both are <link>ed in framework.html, so there
   is no @font-face here.
   ========================================================================== */
/* ==========================================================================
   2. DESIGN TOKENS
   ========================================================================== */
:root {
  /* ---- Brand palette ("Engage_2025 Color scheme") ----------------------- */
  --color-navy: #000032;
  --color-mist: #dce6f0;
  --color-blue: #3b91ff;
  --color-orange: #ff7f00;
  --color-orange-dark: #ce5c0b;
  --color-white: #ffffff;
  --color-black: #000000;
  /* ---- Derived shades (mixed from the brand colours) -------------------- */
  --color-navy-soft: color-mix(in srgb, var(--color-navy) 88%, var(--color-white));
  /* text on white */
  --color-mist-light: color-mix(in srgb, var(--color-mist) 40%, var(--color-white));
  /* tinted surface */
  --color-mist-dark: color-mix(in srgb, var(--color-mist) 70%, var(--color-navy));
  /* borders on white */
  --color-orange-deep: color-mix(in srgb, var(--color-orange-dark) 70%, var(--color-navy));
  /* orange text on light: 5.7:1 on mist, 7:1 on white */
  --color-blue-strong: color-mix(in srgb, var(--color-blue) 60%, var(--color-navy));
  /* blue text on light: 6.9:1 on white, 5.5:1 on mist */
  --color-blue-deep: color-mix(in srgb, var(--color-blue) 70%, var(--color-navy));
  /* white text on it: 5.6:1 */
  --color-raised: color-mix(in srgb, var(--color-blue) 14%, var(--color-navy));
  /* dark mode: panels and dialogs */
  --color-raised-alt: color-mix(in srgb, var(--color-blue) 22%, var(--color-navy));
  /* dark mode: cards on a panel */
  --color-footer: light-dark(color-mix(in srgb, var(--color-mist) 82%, var(--color-navy)),
      color-mix(in srgb, var(--color-blue) 8%, var(--color-navy)));
  /* a bit darker than the page in light mode, navy in dark mode */
  --color-footer-edge: light-dark(color-mix(in srgb, var(--color-navy) 18%, transparent),
      color-mix(in srgb, var(--color-mist) 20%, transparent));
  /* ---- Semantic colours: what a colour is FOR ----------------------------
     Written as light-dark(light mode, dark mode). Which one applies comes from
     color-scheme: dark by default, or the visitor's choice
     (html[data-theme], see section 3). A part of the page can be pinned to one
     mode with color-scheme. */
  --color-bg: light-dark(var(--color-mist), var(--color-navy));
  /* page background */
  --color-text: light-dark(var(--color-navy), var(--color-mist));
  /* text on the page */
  --color-heading: light-dark(var(--color-navy), var(--color-white));
  --color-link: light-dark(var(--color-orange-deep), var(--color-orange));
  /* link on the page */
  --color-link-hover: light-dark(var(--color-navy), var(--color-white));
  --color-surface: light-dark(var(--color-white), var(--color-raised));
  /* panels and dialogs */
  --color-surface-alt: light-dark(var(--color-mist-light), var(--color-raised-alt));
  /* tinted tiles, table headers */
  --color-card: light-dark(var(--color-white), var(--color-raised-alt));
  /* a card on a panel */
  --color-ink: light-dark(var(--color-navy-soft), var(--color-mist));
  /* text on a surface */
  --color-ink-heading: light-dark(var(--color-navy), var(--color-white));
  /* headings on a surface */
  --color-ink-link: light-dark(var(--color-orange-deep), var(--color-orange));
  /* link on a surface */
  --color-accent-text: light-dark(var(--color-blue-deep), var(--color-blue));
  /* blue icons and marks on a surface */
  --color-muted: light-dark(color-mix(in srgb, var(--color-navy) 66%, var(--color-white)),
      color-mix(in srgb, var(--color-mist) 72%, var(--color-navy)));
  /* 5.7:1 on mist, 7:1 on dark surfaces */
  --color-primary: var(--color-orange);
  /* buttons. Always navy text: white on orange fails contrast */
  --color-primary-hover: color-mix(in srgb, var(--color-orange) 80%, var(--color-white));
  /* lighter orange: navy text 9.5:1 */
  --color-on-primary: var(--color-navy);
  --color-accent: var(--color-blue);
  --color-border: light-dark(var(--color-mist-dark), color-mix(in srgb, var(--color-mist) 22%, transparent));
  --color-hairline: light-dark(var(--color-mist), color-mix(in srgb, var(--color-mist) 18%, transparent));
  --color-edge: light-dark(transparent, color-mix(in srgb, var(--color-mist) 14%, transparent));
  /* dark mode: shadows are invisible on navy, so a faint edge lifts a box */
  --color-control-border: light-dark(color-mix(in srgb, var(--color-mist) 60%, var(--color-navy)),
      color-mix(in srgb, var(--color-mist) 50%, transparent));
  /* input edges: 3:1 */
  --color-field: light-dark(var(--color-white), color-mix(in srgb, var(--color-navy) 55%, var(--color-raised)));
  --color-focus: var(--color-blue);
  --color-danger: light-dark(#c0392b, #ff8f80);
  /* red notices on a surface */
  --color-success: light-dark(#2e7d32, #7fdc8c);
  --color-ambassador: light-dark(#006cb7, #5aaaf0);
  /* HCL Ambassador */
  --color-lifetime: light-dark(#8a6f2b, #e2c46c);
  /* HCL Lifetime Ambassador */
  --color-badge: light-dark(var(--color-navy), var(--color-raised-alt));
  --color-orange-tint: light-dark(color-mix(in srgb, var(--color-orange) 12%, var(--color-white)),
      color-mix(in srgb, var(--color-orange) 22%, var(--color-raised-alt)));
  --color-blue-tint: light-dark(color-mix(in srgb, var(--color-blue) 15%, var(--color-white)),
      color-mix(in srgb, var(--color-blue) 30%, var(--color-raised-alt)));
  --color-tooltip: light-dark(var(--color-navy), color-mix(in srgb, var(--color-blue) 30%, var(--color-navy)));
  --color-overlay: color-mix(in srgb, var(--color-navy) 75%, transparent);
  /* behind a dialog */
  /* Navigation: a light bar in light mode, navy in dark mode. */
  --color-nav: light-dark(color-mix(in srgb, var(--color-white) 75%, var(--color-mist)), var(--color-navy));
  --color-nav-scrolled: color-mix(in srgb, var(--color-nav) 92%, transparent);
  --color-nav-text: light-dark(var(--color-navy), var(--color-mist));
  --color-nav-page: light-dark(var(--color-blue-strong), var(--color-orange));
  /* current page link: blue in light mode, with an orange underline */
  --color-nav-page-line: var(--color-orange);
  --color-nav-button: light-dark(var(--color-blue-strong), var(--color-mist));
  /* menu and theme buttons: blue in light mode, mist in dark mode */
  /* Hero, chips, bands (they sit on the photo). */
  --color-wash: light-dark(var(--color-mist), var(--color-navy));
  /* the colour laid over the photo */
  --color-hero-accent: light-dark(color-mix(in srgb, var(--color-orange) 80%, var(--color-navy)), var(--color-orange));
  /* accent words in the hero title; light mode: #cc660a, 3:1 on the pale veil */
  --color-chip: light-dark(color-mix(in srgb, var(--color-white) 72%, transparent), color-mix(in srgb, var(--color-navy) 55%, transparent));
  --color-chip-border: light-dark(color-mix(in srgb, var(--color-navy) 25%, transparent), color-mix(in srgb, var(--color-mist) 40%, transparent));
  --color-band: light-dark(color-mix(in srgb, var(--color-white) 65%, transparent),
      color-mix(in srgb, color-mix(in srgb, var(--color-blue) 16%, var(--color-navy)) 92%, transparent));
  --color-band-edge: light-dark(color-mix(in srgb, var(--color-navy) 12%, transparent), color-mix(in srgb, var(--color-mist) 12%, transparent));
  /* Hero image veiled from the left, lighter to the right so the photo shows. */
  --veil-mid: light-dark(color-mix(in srgb, var(--color-wash) 90%, transparent), color-mix(in srgb, var(--color-wash) 88%, transparent));
  --veil-end: light-dark(color-mix(in srgb, var(--color-wash) 74%, transparent), color-mix(in srgb, var(--color-wash) 52%, transparent));
  /* pale photos need more veil for navy text */
  --gradient-page: linear-gradient(90deg,
      light-dark(color-mix(in srgb, var(--color-wash) 92%, transparent), color-mix(in srgb, var(--color-wash) 100%, transparent)) 0%,
      var(--veil-mid) 40%,
      var(--veil-end) 100%);
  /* ---- Sponsor tiers ----------------------------------------------------- */
  --tier-diamond: #b9f2ff;
  --tier-sapphire: #0f52ba;
  --tier-platinum: #e5e4e2;
  --tier-gold: #ffd700;
  --tier-silver: #c0c0c0;
  --tier-bronze: #cd7f32;
  --tier-neutral: #dfe3ea;
  /* sponsors whose tier is not decided yet */
  /* ---- Session tracks (a coloured edge, never the only signal) ------------ */
  --track-admin: light-dark(#2d5a8c, #5b9be0);
  --track-dev: #00a86b;
  --track-emerging: #9d4edd;
  --track-bus: var(--color-blue);
  --track-commercial: var(--tier-gold);
  --track-roundtable: light-dark(#5c4742, #b08a80);
  --track-other: #7b7b7b;
  --track-workshop: light-dark(#c41e3a, #e0475f);
  --track-general: var(--color-orange);
  /* ---- Typography -------------------------------------------------------- */
  --font-body: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-heading: "Jost", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Fluid sizes: clamp(smallest, preferred, largest). */
  --text-xs: 0.8rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: clamp(1.1rem, 1.02rem + 0.4vw, 1.25rem);
  /* .lead text */
  --text-h5: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  --text-h4: clamp(1.15rem, 1rem + 0.8vw, 1.75rem);
  --text-h3: clamp(1.5rem, 1.2rem + 1.2vw, 2.25rem);
  --text-h2: clamp(1.85rem, 1.4rem + 1.8vw, 2.625rem);
  --text-h1: clamp(2.5rem, 1.6rem + 3.6vw, 4.25rem);
  --leading-base: 1.5;
  --leading-tight: 1.2;
  --weight-body: 400;
  --weight-medium: 600;
  --weight-bold: 800;
  /* ---- Space (4px steps at the default text size) ------------------------ */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  /* ---- Shape, depth, motion ---------------------------------------------- */
  --container-max: 75rem;
  --gutter: var(--space-4);
  --radius-s: 0.25rem;
  --radius-m: 0.625rem;
  --radius-l: 1.25rem;
  --radius-pill: 999px;
  /* Navy-tinted in light mode, black in dark mode, plus the faint edge (--color-edge, invisible in light mode). */
  --shadow-soft: light-dark(rgb(0 0 50 / 0.10), rgb(0 0 0 / 0.30));
  --shadow-mid: light-dark(rgb(0 0 50 / 0.14), rgb(0 0 0 / 0.40));
  --shadow-strong: light-dark(rgb(0 0 50 / 0.20), rgb(0 0 0 / 0.50));
  --shadow-deep: light-dark(rgb(0 0 50 / 0.35), rgb(0 0 0 / 0.60));
  --shadow-1: 0 0 0 1px var(--color-edge), 0 1px 2px var(--shadow-soft), 0 6px 20px var(--shadow-mid);
  --shadow-2: 0 0 0 1px var(--color-edge), 0 4px 8px var(--shadow-soft), 0 14px 32px var(--shadow-strong);
  --shadow-3: 0 0 0 1px var(--color-edge), 0 12px 40px var(--shadow-deep);
  --transition: 0.2s ease-in-out;
  --focus-ring: 3px solid var(--color-focus);
  --nav-height: 3.4rem;
  /* 2rem logo + padding + border; 5.3rem from lg */
  /* Stacking order */
  --z-raised: 10;
  --z-nav: 100;
  --z-modal: 200;
}
@media (min-width: 62em) {
  :root {
    --nav-height: 5.3rem;
  }
}
@media (min-width: 62em) {
  :root {
    --gutter: var(--space-5);
  }
}
/* ==========================================================================
   3. RESET AND BASE
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  color-scheme: dark;
  /* dark by default; a visitor's choice for light is set below */
  scrollbar-gutter: stable;
  /* the page doesn't shift when a dialog hides the scrollbar */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor jumps stop below the fixed navigation. */
  scroll-padding-top: calc(var(--nav-height) + var(--space-4));
}
/* The visitor's choice from the theme button (js/engage.js, js/theme-init.js).
   No attribute = dark. */
html[data-theme="light"] {
  color-scheme: light;
}
/* The page behind an open dialog doesn't scroll. */
html:has(dialog[open]) {
  overflow: hidden;
}
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  /* short pages: .page grows so the footer sits at the bottom of the screen */
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-body);
  line-height: var(--leading-base);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
ul,
ol,
dl,
figure,
blockquote,
fieldset {
  margin: 0;
}
ul,
ol {
  padding: 0;
  list-style: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
  color: var(--color-heading);
  font-family: var(--font-heading);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: 0.5px;
  text-wrap: balance;
}
h1 {
  font-size: var(--text-h1);
  letter-spacing: -0.01em;
}
h2 {
  font-size: var(--text-h2);
  letter-spacing: 0;
}
h3 {
  font-size: var(--text-h3);
}
h4 {
  font-size: var(--text-h4);
}
/* Extra air above an h4 that follows other content; beats the .stack / .dialog__body gaps. */
*+h4,
.stack>*+h4,
.dialog__body>*+h4,
.dialog__body>[data-title]>*+h4 {
  margin-top: var(--space-6);
}
h5 {
  font-size: var(--text-h5);
  letter-spacing: 0;
}
h6 {
  font-size: var(--text-base);
  letter-spacing: 0;
}
a {
  color: var(--color-link);
  text-decoration: none;
}
a:hover {
  color: var(--color-link-hover);
}
img,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
button {
  cursor: pointer;
}
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}
[hidden] {
  display: none !important;
}
/* First thing a keyboard visitor tabs to: jumps over the navigation. */
.skip-link {
  position: fixed;
  top: var(--space-2);
  left: var(--space-2);
  z-index: calc(var(--z-nav) + 1);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: var(--weight-medium);
  transform: translateY(-200%);
}
.skip-link:focus {
  transform: none;
}
@media print {
  html {
    color-scheme: light;
  }
  .site-nav,
  .site-footer,
  .dialog {
    display: none;
  }
}
/* ==========================================================================
   4. LAYOUT
   Layout classes only arrange their children.
   ========================================================================== */
/* Centres content and limits its width. */
.container {
  width: min(100% - 2 * var(--gutter), var(--container-max));
  margin-inline: auto;
}
/* Children one under the other. Override the gap with --space on the element. */
.stack>*+* {
  margin-top: var(--space, var(--space-4));
}
.stack--lg {
  --space: var(--space-6);
}
/* Children side by side that wrap onto a new line (button rows, link lists). */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space, var(--space-2));
}
.cluster--center {
  justify-content: center;
}
/* As many equal columns as fit, each at least --min wide. */
.grid {
  display: grid;
  gap: var(--space, var(--space-4));
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--min, 16rem)), 1fr));
}
/* Text next to an image: stacked on small screens, side by side from md up.
   Default 7/5; use --reverse to put the image first on wide screens. */
.split {
  display: grid;
  gap: var(--space-5);
  align-items: center;
}
@media (min-width: 48em) {
  .split {
    grid-template-columns: 7fr 5fr;
  }
  .split--reverse {
    grid-template-columns: 5fr 7fr;
  }
  .split--reverse> :first-child {
    order: 2;
  }
}
/* ==========================================================================
   5. COMPONENTS
   ========================================================================== */
/* --------------------------------------------------------------------------
   Buttons
   <a class="btn btn--primary" href="...">Pictures</a>
   Modifiers: --primary (orange), --outline, --link (looks like a link),
   --sm (small).
   -------------------------------------------------------------------------- */
.btn {
  display: inline-block;
  padding: var(--space-2) var(--space-5);
  border: 2px solid transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--leading-base);
  text-align: center;
  transition: background-color var(--transition), color var(--transition), border-color var(--transition),
    transform var(--transition), box-shadow var(--transition);
}
.btn:hover {
  color: var(--color-text);
}
.btn--primary {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
  box-shadow: var(--shadow-1);
}
/* Hover lightens the orange (navy on it is 9.5:1); a darker orange only reached 4.9:1. */
.btn--primary:hover {
  border-color: var(--color-primary-hover);
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
  box-shadow: var(--shadow-2);
  transform: translateY(-1px);
}
.btn--outline {
  border-color: var(--color-ink-link);
  color: var(--color-text);
}
.btn--outline:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn--link {
  color: inherit;
}
.btn--link:hover {
  color: var(--color-link);
  text-decoration: underline;
}
.btn--sm {
  padding: var(--space-1) var(--space-4);
  font-size: var(--text-sm);
}
/* Disabled: its own flat colours (muted ink on a tint, 5:1 or more) instead of fading
   the button with opacity, which left about 2.4:1. */
.btn[aria-disabled="true"],
.btn:disabled {
  border-color: transparent;
  background: var(--color-surface-alt);
  box-shadow: none;
  color: var(--color-muted);
  cursor: not-allowed;
  pointer-events: none;
}
/* A button that contains a card (used for popup triggers). */
.btn--block {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  color: inherit;
  text-align: inherit;
}
.btn--block:hover {
  color: inherit;
}
/* --------------------------------------------------------------------------
   Navigation
   <header class="site-nav">
     <div class="container site-nav__inner">
       <a class="site-nav__brand" href="/"><img ...></a>
       <button class="site-nav__toggle" aria-expanded="false" aria-controls="menu">...</button>
       <nav class="site-nav__menu" id="menu" aria-label="Main">
         <a class="site-nav__link" href="/" aria-current="page">Home</a>
   nav.js toggles aria-expanded and sets data-scrolled on the header.
   Without JavaScript the menu is always visible (see .no-js rule below).
   -------------------------------------------------------------------------- */
.site-nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-nav);
  border-bottom: 5px solid color-mix(in srgb, var(--color-blue) 75%, transparent);
  background: color-mix(in srgb, var(--color-nav) 95%, transparent);
  box-shadow: var(--shadow-1);
  transition: background-color 0.5s;
}
.site-nav__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-2);
}
.site-nav__brand {
  margin-right: auto;
}
/* the menu and the buttons sit at the right */
.site-nav__brand img {
  width: auto;
  height: 2rem;
}
.site-nav__toggle {
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: var(--space-1) var(--space-2);
  border: 0;
  background: transparent;
  color: var(--color-nav-button);
  font-size: 1.5rem;
  line-height: 1;
}
/* Theme button (js/engage.js): one button that toggles Dark and Light. The
   icon shows the current choice. Same colour as the menu button. */
.theme-toggle {
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: var(--space-1) var(--space-2);
  border: 0;
  background: transparent;
  color: var(--color-nav-button);
  font-size: 1.25rem;
  line-height: 1;
}
.theme-toggle:hover {
  color: var(--color-nav-text);
}
/* Small screens: the menu is a column that opens under the bar. */
.site-nav__menu {
  display: none;
  flex-basis: 100%;
  flex-direction: column;
  align-items: flex-end;
  padding-block: var(--space-2);
}
.site-nav__toggle[aria-expanded="true"]+.site-nav__menu {
  display: flex;
}
.site-nav__link {
  padding: var(--space-3) var(--space-2);
  /* 44px+ touch target in the mobile column */
  color: var(--color-nav-text);
  font-size: 1.1rem;
  font-weight: var(--weight-body);
}
.site-nav__link:hover {
  color: var(--color-nav-text);
  box-shadow: 0 2px 0 var(--color-blue);
}
.site-nav__link[aria-current="page"] {
  color: var(--color-nav-page);
  font-weight: var(--weight-bold);
  box-shadow: 0 2px 0 var(--color-nav-page-line);
}
/* After the visitor scrolls: the bar gets a little more solid and blurred, so the
   links (and the orange current page) keep their colours. */
.site-nav[data-scrolled] {
  background: var(--color-nav-scrolled);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-2);
}
@media (min-width: 62em) {
  .site-nav {
    background: var(--color-nav);
  }
  .site-nav[data-scrolled] {
    background: var(--color-nav-scrolled);
  }
  .site-nav__brand img {
    height: 4rem;
  }
  .site-nav__link {
    padding-block: var(--space-1);
  }
  .site-nav__toggle {
    display: none;
  }
  .site-nav__menu {
    display: flex;
    flex-basis: auto;
    flex-direction: row;
    gap: var(--space-2);
    padding-block: 0;
    order: 1;
    /* before the theme button, which comes first in the HTML */
  }
  .theme-toggle {
    order: 2;
    margin-left: var(--space-2);
  }
}
/* No JavaScript: the toggle can't work, so show the menu and hide the button. */
.no-js .site-nav__toggle,
.no-js .theme-toggle {
  display: none;
}
.no-js .site-nav__menu {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
/* --------------------------------------------------------------------------
   Page
   The whole page sits on one hero image under a veil (dark in dark mode, pale in
   light mode). The image is set per page, inline, as --page-image, so its URL is
   relative to the page (a URL inside a CSS file would be relative to the
   stylesheet). The image stays in the viewport while the page scrolls. A page
   without an image just leaves the style attribute out.
   <div class="page" style="--page-image: url('img/introimages/arena.webp')">
     <section class="page-hero">...</section>
     <main class="page-main">...</main>
   </div>
   -------------------------------------------------------------------------- */
.page {
  position: relative;
  flex: 1 0 auto;
  padding-top: var(--nav-height);
  padding-bottom: var(--space-2);
  background: var(--color-bg);
  color: var(--color-heading);
  clip-path: inset(0);
  /* the fixed layer below only shows inside the page, not over the footer */
  overflow-x: clip;
  /* clip-path doesn't stop overflow from widening the page: the hidden tooltips ([data-tip]::after)
     of logos near the right edge did, which pushed the fixed nav's buttons off screen */
}
/* The photo and the veil over it stay in the viewport; the content scrolls over them.
   A fixed layer instead of background-attachment: fixed, which iOS ignores. A page
   without --page-image has no photo, just the plain page colour. */
.page::before {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--gradient-page), var(--page-image, none) center / cover no-repeat;
}
.page>* {
  position: relative;
}
@media print {
  .page::before {
    display: none;
  }
}
.page-hero {
  padding-block: var(--space-7) var(--space-6);
  text-align: center;
  text-shadow: 0 1px 14px color-mix(in srgb, var(--color-bg) 70%, transparent);
}
.page-hero>*+* {
  margin-top: var(--space-3);
}
.page-hero__title {
  text-transform: none;
}
.page-hero__accent {
  color: light-dark(var(--color-hero-accent), var(--color-blue));
}
/* running text: orange in light mode (trying it), blue in dark mode */
:is(h1, h2, h3, h4, h5, h6).page-hero__accent,
:is(h1, h2, h3, h4, h5, h6) .page-hero__accent {
  color: var(--color-hero-accent);
}
/* orange in headings */
/* Date and venue under the hero title. */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-4);
}
.chip {
  padding: var(--space-1) var(--space-4);
  border: 1px solid var(--color-chip-border);
  border-radius: var(--radius-pill);
  background: var(--color-chip);
  color: var(--color-heading);
  font-weight: var(--weight-medium);
}
.chip i {
  margin-right: var(--space-1);
  color: var(--color-ink-link);
}
.hero-cta {
  margin-top: var(--space-5);
}
/* The sponsor carousel under the hero buttons (home page). */
.hero-sponsors {
  margin-top: var(--space-6);
}
/* A short title above a group of cards, with an orange rule. */
.section-title {
  margin-bottom: var(--space-5);
  font-size: var(--text-h3);
  text-align: center;
}
.section-title::after {
  content: "";
  display: block;
  width: 3.5rem;
  height: 4px;
  margin: var(--space-2) auto 0;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
}
/* A full-width section on a slightly lighter surface, to break up the stack of
   panels. Put a .container inside it. */
.band {
  margin-top: var(--space-6);
  padding-block: var(--space-6);
  border-block: 1px solid var(--color-band-edge);
  background: var(--color-band);
}
/* The last band meets the footer without a strip of photo in between. */
.page-main>.band:last-child {
  margin-bottom: calc(-1 * var(--space-6));
}
.page-main {
  padding-block: var(--space-4) var(--space-6);
}
.lead {
  font-size: var(--text-lg);
  font-weight: var(--weight-body);
}
/* Row of links to sections further down the page. */
.page-links {
  margin-block: var(--space-4);
  padding-block: var(--space-2);
  background: color-mix(in srgb, var(--color-blue) 30%, transparent);
  text-align: center;
}
/* --------------------------------------------------------------------------
   Panel: a white raised box with dark text. Use for the main content.
   Links inside are dark orange so they stay readable on white.
   -------------------------------------------------------------------------- */
.panel {
  padding: var(--space-5);
  border-radius: var(--radius-l);
  background: var(--color-surface);
  box-shadow: var(--shadow-1);
  color: var(--color-ink);
}
/* :where() keeps the specificity of a plain link, and leaves buttons alone. */
.panel a:where(:not(.btn)) {
  color: var(--color-ink-link);
  text-decoration: underline;
}
.panel a:where(:not(.btn)):hover {
  color: var(--color-ink-heading);
}
.panel h1,
.panel h2,
.panel h3,
.panel h4,
.panel h5 {
  color: var(--color-ink-heading);
}
.panel--accent {
  --color-ink-heading: var(--color-navy);
  background: var(--color-blue);
  color: var(--color-navy);
}
.panel--accent a {
  color: var(--color-navy);
}
/* --------------------------------------------------------------------------
   Info card: a panel that opens a dialog (or links away). Image and text
   side by side from md up. Wrap it in <a data-dialog> or <button>.
   <a class="info-card panel" href="..." data-dialog>
     <div class="info-card__body">...</div>
     <img class="info-card__image" ...>
   </a>
   Modifier --accent: blue panel with the image on the left.
   -------------------------------------------------------------------------- */
.info-card {
  display: grid;
  gap: var(--space-4);
  align-items: center;
  margin-top: var(--space-4);
  color: var(--color-ink);
  text-align: left;
  /* A top accent edge that follows the rounded corners. */
  box-shadow: inset 0 5px 0 var(--color-blue), var(--shadow-1);
  transition: transform var(--transition), box-shadow var(--transition);
}
.info-card[data-dialog]:hover {
  color: var(--color-ink);
  box-shadow: inset 0 5px 0 var(--color-blue), var(--shadow-2);
  transform: translateY(-3px);
}
/* Cards that open a dialog say so. */
.info-card[data-dialog] .info-card__body::after {
  content: "More details \2192";
  display: block;
  margin-top: var(--space-3);
  color: var(--color-ink-link);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}
/* Light text on a deeper blue (white on the brand blue is only 3.3:1). */
.info-card--accent {
  background: var(--color-blue-deep);
  color: var(--color-white);
  box-shadow: inset 0 5px 0 var(--color-white), var(--shadow-1);
}
.info-card--accent[data-dialog]:hover {
  color: var(--color-white);
  box-shadow: inset 0 5px 0 var(--color-white), var(--shadow-2);
}
.info-card--accent h2,
.info-card--accent a {
  color: var(--color-white);
}
.info-card--accent[data-dialog] .info-card__body::after {
  color: var(--color-white);
}
.info-card__image {
  width: 100%;
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-1);
}
.info-card__body h2 {
  margin-bottom: var(--space-2);
}
.info-card__body>*+* {
  margin-top: var(--space-3);
}
@media (min-width: 48em) {
  .info-card {
    grid-template-columns: 7fr 5fr;
  }
  .info-card--accent {
    grid-template-columns: 5fr 7fr;
  }
  .info-card--accent .info-card__image {
    order: -1;
  }
}
.back-to-top {
  display: block;
  margin-block: var(--space-2) var(--space-4);
  color: var(--color-text);
  font-size: var(--text-sm);
  text-align: right;
}
/* --------------------------------------------------------------------------
   Feature: icon, title and text on a light tile ("Why attend").
   <div class="grid" style="--min: 15rem">
     <div class="feature"><i class="fas fa-users feature__icon"></i><h3 class="feature__title">...
   -------------------------------------------------------------------------- */
.feature {
  padding: var(--space-4);
  border-radius: var(--radius-m);
  background: var(--color-surface-alt);
  box-shadow: var(--shadow-1);
  color: var(--color-ink);
  text-align: center;
  transition: transform var(--transition), box-shadow var(--transition);
}
.feature:hover {
  box-shadow: var(--shadow-2);
  transform: translateY(-3px);
}
/* Scroll reveal (js/engage.js): hidden until it enters the screen, then fades up. */
html:not(.no-js) [data-reveal]:not([data-revealed]) {
  opacity: 0;
}
[data-revealed] {
  animation: reveal 0.5s ease-out;
}
@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(1.25rem);
  }
}
@media print {
  html:not(.no-js) [data-reveal]:not([data-revealed]) {
    opacity: 1;
  }
}
/* Icon in a round tinted badge; every other one is blue. */
.feature__icon {
  --fa-display: inline-flex;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-orange-tint);
  color: var(--color-ink-link);
  font-size: 1.5rem;
}
.feature:nth-child(even) .feature__icon {
  background: var(--color-blue-tint);
  color: var(--color-ink-heading);
}
.feature__title {
  margin-bottom: var(--space-2);
  color: var(--color-ink-heading);
  font-size: var(--text-h5);
  font-weight: var(--weight-bold);
}
/* --------------------------------------------------------------------------
   Cards, badges, tables, forms (shared by several pages)
   -------------------------------------------------------------------------- */
.card {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  background: var(--color-card);
  color: var(--color-ink);
}
.badge {
  display: inline-block;
  padding: 0.2em 0.6em;
  border-radius: var(--radius-s);
  background: var(--color-badge);
  color: var(--color-mist);
  font-size: 0.75em;
  font-weight: var(--weight-bold);
  line-height: 1.3;
}
.text-muted {
  color: var(--color-muted);
}
.text-danger {
  color: var(--color-danger);
}
.table {
  width: 100%;
  border-collapse: collapse;
}
.table th,
.table td {
  padding: var(--space-1) var(--space-2) var(--space-1) 0;
  border-bottom: 1px solid var(--color-orange);
  font-size: var(--text-sm);
  text-align: left;
  vertical-align: top;
}
.table th {
  border-bottom-width: 2px;
  font-weight: var(--weight-bold);
}
.table tbody th {
  font-weight: var(--weight-body);
}
/* a row label in a data table */
/* Form fields.
   <div class="field">
     <label class="field__label" for="x">Email</label>
     <input class="input" id="x" type="email">
   </div> */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.field__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.field__label--required::after {
  content: " *";
}
.input,
.select,
.textarea {
  width: 100%;
  min-height: 2.5rem;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-control-border);
  border-radius: var(--radius-s);
  background: var(--color-field);
  color: var(--color-ink);
}
.input::placeholder,
.textarea::placeholder {
  color: var(--color-muted);
}
.input:focus,
.select:focus,
.textarea:focus {
  border-color: var(--color-orange);
  outline: 0;
  box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--color-orange) 30%, transparent);
}
/* Dark variant for the newsletter strip. */
.input--dark {
  border-color: color-mix(in srgb, var(--color-mist) 50%, transparent);
  background: transparent;
  color: var(--color-mist);
  color-scheme: dark;
}
.input--dark::placeholder {
  color: color-mix(in srgb, var(--color-mist) 60%, transparent);
}
/* --------------------------------------------------------------------------
   Carousel: a scroll-snap strip. Swipe on touch, scroll bar or arrows on
   desktop. carousel.js adds autoplay (stops on hover and with reduced motion),
   arrow buttons, and an optional seamless loop.
   <div class="carousel" data-carousel="auto loop">
     <ul class="carousel__track">
       <li class="carousel__item">...</li>
   Items per view: --per-view (changes with the screen width below).
   -------------------------------------------------------------------------- */
.carousel {
  --per-view: 2;
  --gap: var(--space-2);
  position: relative;
}
@media (min-width: 22.5em) {
  .carousel {
    --per-view: 3;
  }
}
@media (min-width: 37.5em) {
  .carousel {
    --per-view: 4;
  }
}
@media (min-width: 56em) {
  .carousel {
    --per-view: 5;
  }
}
@media (min-width: 69em) {
  .carousel {
    --per-view: 6;
  }
}
@media (min-width: 81em) {
  .carousel {
    --per-view: 7;
  }
}
.carousel__track {
  display: flex;
  gap: var(--gap);
  padding-block: var(--space-2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.carousel__track::-webkit-scrollbar {
  display: none;
}
.carousel__item {
  flex: 0 0 calc((100% - (var(--per-view) - 1) * var(--gap)) / var(--per-view));
  scroll-snap-align: start;
}
.carousel__btn {
  position: absolute;
  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  transform: translateY(-50%);
  border: 1px solid var(--color-orange);
  border-radius: 50%;
  background: var(--color-white);
  color: var(--color-orange);
}
.carousel__btn:hover {
  background: var(--color-orange);
  color: var(--color-white);
}
.carousel__btn--prev {
  left: -0.5rem;
}
.carousel__btn--next {
  right: -0.5rem;
}
/* Pause / play for the autoplay, above the strip's right edge. */
.carousel__pause {
  position: absolute;
  top: calc(-1 * var(--space-6));
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--color-orange);
  border-radius: 50%;
  background: var(--color-navy);
  color: var(--color-orange);
  font-size: var(--text-xs);
}
.carousel__pause:hover {
  background: var(--color-orange);
  color: var(--color-navy);
}
/* --------------------------------------------------------------------------
   Sponsors
   .sponsor-tile   one logo in a white box with a coloured edge. The edge
                   colour comes from data-tier (see below). A link or a
                   button that opens a dialog.
   .sponsor-tier   a titled group of tiles on the sponsors page.
                   Modifiers --large, --medium, --small set the tile size.
   -------------------------------------------------------------------------- */
[data-tier="Diamond"] {
  --tier-color: var(--tier-diamond);
}
[data-tier="Sapphire"] {
  --tier-color: var(--tier-sapphire);
}
[data-tier="Platinum"] {
  --tier-color: var(--tier-platinum);
}
[data-tier="Gold"] {
  --tier-color: var(--tier-gold);
}
[data-tier="Silver"] {
  --tier-color: var(--tier-silver);
}
[data-tier="Bronze"] {
  --tier-color: var(--tier-bronze);
}
/* "Sponsors": no tier decided yet. Uncoloured, and listed last (tierOrder 6). */
[data-tier="Sponsors"] {
  --tier-color: var(--tier-neutral);
}
.sponsor-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: var(--space-2);
  border: 0;
  border-bottom: 4px solid var(--tier-color, var(--color-white));
  border-radius: var(--radius-m);
  background: var(--color-white);
  /* The faint outline keeps pale tiers (Diamond, Platinum) visible on white. */
  box-shadow: var(--shadow-1), inset 0 0 0 1px color-mix(in srgb, var(--color-navy) 14%, transparent);
  transition: transform var(--transition), box-shadow var(--transition);
}
.sponsor-tile:hover {
  box-shadow: var(--shadow-2), inset 0 0 0 1px color-mix(in srgb, var(--color-navy) 14%, transparent);
  transform: translateY(-3px);
}
.sponsor-tile img {
  max-height: 100%;
  object-fit: contain;
}
/* A sponsor without a logo: its name in place of the image. */
.sponsor-tile__name {
  color: var(--color-navy);
  font-weight: var(--weight-bold);
  text-align: center;
  overflow-wrap: anywhere;
}
/* In the carousel the tier is spelled out in a small chip under the logo. */
.carousel .sponsor-tile {
  flex-direction: column;
  gap: var(--space-1);
  height: 7rem;
}
/* The logo fills the space above the chip, so every chip sits at the same height. */
.carousel .sponsor-tile img {
  flex: 1;
  min-height: 0;
  width: 100%;
  object-fit: contain;
}
.carousel .sponsor-tile::after {
  content: attr(data-tier);
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--tier-color, var(--color-border));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-navy) 25%, transparent);
  color: var(--color-navy);
  font-size: 0.65rem;
  font-weight: var(--weight-bold);
  letter-spacing: 0.05em;
  line-height: 1.5;
  text-transform: uppercase;
}
.sponsor-tier+.sponsor-tier,
.panel>p+.sponsor-tier {
  margin-top: var(--space-5);
}
.sponsor-tier__title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  color: var(--color-ink-heading);
  font-size: var(--text-h4);
}
/* The tier name as a chip in the tier colour. */
.sponsor-tier__label {
  padding: 0 var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--tier-color, var(--color-border));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-navy) 25%, transparent);
  color: var(--color-navy);
}
.sponsor-tier__title::before,
.sponsor-tier__title::after {
  content: "";
  flex: 1;
  height: 3px;
  background: var(--tier-color, var(--color-border));
}
.sponsor-tier__list {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min, 14rem)), 1fr));
}
.sponsor-tier__list .sponsor-tile {
  height: var(--tile-height, 6.875rem);
  padding-inline: var(--space-4);
}
.sponsor-tier__list img {
  width: var(--logo-width, 12.5rem);
}
.sponsor-tier--large {
  --min: 100%;
}
.sponsor-tier--medium {
  --min: 18rem;
}
.sponsor-tier--compact {
  --min: 14rem;
  --tile-height: 5rem;
  --logo-width: 9rem;
}
/* between medium (Gold) and small (Bronze): Silver */
.sponsor-tier--small {
  --min: 11rem;
  --tile-height: 3.5rem;
  --logo-width: 6.25rem;
}
/* --------------------------------------------------------------------------
   Tooltip: text bubble on hover and keyboard focus. Replaces Bootstrap
   popovers. <a data-tip="Apps that run your business" href="...">
   -------------------------------------------------------------------------- */
[data-tip] {
  position: relative;
}
[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  z-index: var(--z-raised);
  width: max-content;
  max-width: min(18rem, 80vw);
  padding: var(--space-2) var(--space-3);
  transform: translateX(-50%);
  border-radius: var(--radius-s);
  background: var(--color-tooltip);
  box-shadow: var(--shadow-1);
  color: var(--color-white);
  font-size: var(--text-xs);
  line-height: var(--leading-base);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}
[data-tip]:hover::after,
[data-tip]:focus-visible::after {
  opacity: 1;
}
.product-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-3) var(--space-5);
}
.product-list__logo {
  height: 3.5rem;
  width: auto;
}
/* --------------------------------------------------------------------------
   Footer and newsletter
   -------------------------------------------------------------------------- */
/* Three columns from md: newsletter, links, social. Stacked on small screens. */
.site-footer {
  padding: var(--space-7) 0 var(--space-5);
  border-top: 1px solid var(--color-footer-edge);
  background: var(--color-footer);
  color: var(--color-text);
  font-size: var(--text-sm);
}
.site-footer>.container>*+* {
  margin-top: var(--space-6);
}
.site-footer__grid {
  display: grid;
  gap: var(--space-6);
}
.site-footer__title {
  margin-bottom: var(--space-3);
  font-size: var(--text-h4);
}
.site-footer__heading {
  margin-bottom: var(--space-3);
  font-size: var(--text-sm);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.site-footer__links>li+li {
  margin-top: var(--space-2);
}
.site-footer__links a {
  color: var(--color-text);
}
.site-footer__links a:hover {
  color: var(--color-ink-link);
  text-decoration: underline;
}
.site-footer__note {
  font-style: italic;
}
.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-footer-edge);
}
.social {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.social a {
  color: var(--color-accent-text);
}
.social a:hover {
  color: var(--color-ink-link);
}
.social i {
  width: 1.25em;
  transition: transform var(--transition);
}
.social a:hover i {
  transform: scale(1.3);
}
@media (min-width: 48em) {
  .site-footer__grid {
    grid-template-columns: 5fr 3fr 4fr;
  }
}
/* --------------------------------------------------------------------------
   Consent (js/engage.js, js/consent-init.js)
   <html data-consent="granted|declined|unset">. Whatever needs stored data is
   marked data-consent-required and is hidden until the visitor agrees; the
   opposite, data-consent-missing, is shown until then. In the legal notice
   data-consent-state="<value>" shows the current choice. The banner sits in the
   footer block, outside .page, so position: fixed is not clipped.
   -------------------------------------------------------------------------- */
html:not([data-consent="granted"]) [data-consent-required],
html[data-consent="granted"] [data-consent-missing],
[data-consent-state],
.consent {
  display: none;
}
html[data-consent="granted"] [data-consent-state="granted"],
html[data-consent="declined"] [data-consent-state="declined"],
html[data-consent="unset"] [data-consent-state="unset"] {
  display: revert;
}
.consent {
  position: fixed;
  inset: auto 0 0;
  z-index: var(--z-nav);
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-top: 1px solid var(--color-footer-edge);
  background: var(--color-footer);
  box-shadow: var(--shadow-3);
  color: var(--color-text);
  /* like the footer */
  font-size: var(--text-sm);
}
html[data-consent="unset"] .consent {
  display: flex;
}
/* Room under the footer, so the banner never covers its last line. */
html[data-consent="unset"] .site-footer {
  padding-bottom: 12rem;
}
.consent__text {
  max-width: 60rem;
}
.consent__text a {
  color: var(--color-text);
  text-decoration: underline;
}
.consent__text a:hover {
  color: var(--color-ink-link);
}
.consent__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
@media (min-width: 48em) {
  .consent {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    padding-inline: var(--space-6);
  }
  .consent__actions {
    flex: none;
  }
  html[data-consent="unset"] .site-footer {
    padding-bottom: 8rem;
  }
}
@media print {
  .consent {
    display: none;
  }
}
/* --------------------------------------------------------------------------
   Dialog: the one modal for the whole site, a native <dialog>.
   js/engage.js creates it on first use. The browser provides the focus trap,
   the Escape key and returning focus to the trigger.
     <dialog class="dialog dialog--lg" data-tier="Gold">
       <header class="dialog__header">
         <h2 class="dialog__title">...</h2>
         <button class="dialog__close" data-dialog-close aria-label="Close">
       </header>
       <div class="dialog__body">...</div>
       <footer class="dialog__footer">...</footer>
   Sizes: default 60rem, --sm, --lg.
   -------------------------------------------------------------------------- */
.dialog {
  width: 100%;
  max-width: none;
  max-height: calc(100dvh - 2 * var(--space-4));
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--radius-l);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
  color: var(--color-ink);
  overflow: hidden;
}
.dialog[open] {
  display: flex;
  flex-direction: column;
  animation: dialog-in 0.2s ease-out;
}
.dialog::backdrop {
  background: var(--color-overlay);
}
.dialog--sm {
  --dialog-width: 28rem;
}
.dialog--lg {
  --dialog-width: 64rem;
}
/* Full screen width up to the md range; from lg up the dialog gets its own width. */
@media (min-width: 62em) {
  .dialog {
    width: min(100% - 2 * var(--space-4), var(--dialog-width, 60rem));
  }
}
@keyframes dialog-in {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
}
.dialog__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-4) 0;
}
.dialog__title {
  color: var(--color-ink-heading);
  font-size: var(--text-h3);
}
/* A sponsor dialog gets a bar in its tier colour; the name stays navy. */
.dialog[data-tier] {
  border-top: 8px solid var(--tier-color);
}
.dialog__close {
  flex: none;
  margin-inline-start: auto;
  /* stays on the right when the title is hidden */
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--color-muted);
  font-size: 1.75rem;
  line-height: 1;
}
.dialog__close:hover {
  background: var(--color-surface-alt);
  color: var(--color-ink-heading);
}
.dialog__body {
  flex: 1;
  padding: var(--space-3) var(--space-2) var(--space-4);
  overflow-y: auto;
}
.dialog__body a:where(:not(.btn)) {
  color: var(--color-ink-link);
  text-decoration: underline;
}
.dialog__body>*+* {
  margin-top: var(--space-3);
}
/* A container that holds an iframe (the subscribe form) fills the dialog. */
.dialog__body .container:has(> iframe) {
  width: 100%;
}
.dialog__footer {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
}
.dialog__status {
  color: var(--color-muted);
  text-align: center;
}
@media (min-width: 48em) {
  .dialog__header {
    padding-inline: var(--space-5);
  }
  .dialog__body {
    padding-inline: var(--space-5);
  }
  .dialog__footer {
    padding-inline: var(--space-5);
  }
}
/* While the theme button switches the colours (js/engage.js): no fades, so nothing is half-changed. */
html.theme-switching *,
html.theme-switching *::before,
html.theme-switching *::after {
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .dialog[open] {
    animation: none;
  }
  html {
    scroll-behavior: auto;
  }
  .site-nav,
  .btn,
  .info-card,
  .feature,
  .sponsor-tile {
    transition: none;
  }
  .btn:hover,
  .info-card[data-dialog]:hover,
  .feature:hover,
  .sponsor-tile:hover {
    transform: none;
  }
}
/* ==========================================================================
   6. UTILITIES
   ========================================================================== */
.text-center {
  text-align: center;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.mt-4 {
  margin-top: var(--space-4);
}
.mb-4 {
  margin-bottom: var(--space-4);
}
/* ==========================================================================
   7. SESSIONS, AGENDA AND SPEAKERS
   Rendered by js/sessions.js from the session feed.
   ========================================================================== */
.notice {
  padding: var(--space-4);
  color: var(--color-muted);
  text-align: center;
}
.notice--error {
  color: var(--color-danger);
}
/* A button that looks like a link (speaker names in a sentence). */
.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-decoration: underline;
}
.link-button:hover {
  text-decoration: none;
}
.badge--topic {
  margin: 0 var(--space-1) var(--space-1) 0;
  background: var(--color-surface-alt);
  box-shadow: inset 0 0 0 1px var(--color-border);
  color: var(--color-ink);
}
/* ---- Tracks ---------------------------------------------------------------
   <div class="track track--admin"> gets a coloured left edge. */
.track {
  --track-color: var(--track-other);
  border: 2px solid var(--color-hairline);
  border-left: 10px solid var(--track-color);
  border-radius: var(--radius-m);
  background: var(--color-card);
  color: var(--color-ink);
}
.track--admin {
  --track-color: var(--track-admin);
}
.track--dev {
  --track-color: var(--track-dev);
}
.track--emerging {
  --track-color: var(--track-emerging);
}
.track--bus {
  --track-color: var(--track-bus);
}
.track--commercial {
  --track-color: var(--track-commercial);
}
.track--roundtable {
  --track-color: var(--track-roundtable);
}
.track--other {
  --track-color: var(--track-other);
}
.track--general {
  --track-color: var(--track-general);
}
.track--workshop {
  --track-color: var(--track-workshop);
}
/* The track legend is always visible: a row of chips, each with its track colour as a dot. */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-block: var(--space-2) var(--space-3);
}
.legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.legend__item::before,
.session__track::before {
  content: "";
  flex: none;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--track-color);
}
/* Preferred sessions: gold star, faint gold background. */
.favorite-star {
  flex: none;
  padding: 0 var(--space-1);
  border: 0;
  background: none;
  color: color-mix(in srgb, var(--color-muted) 75%, var(--color-surface));
  /* about 3.5:1 on the surface */
  font-size: 1.5rem;
  line-height: 1;
}
.favorite-star:hover {
  color: var(--tier-gold);
}
.preferred {
  background-color: color-mix(in srgb, var(--tier-gold) 15%, var(--color-card));
}
.preferred .favorite-star {
  color: var(--tier-gold);
}
.btn--favorite {
  border: 1px solid var(--tier-gold);
  background: transparent;
  color: var(--color-ink-heading);
}
.btn--favorite[aria-pressed="true"] {
  background: var(--tier-gold);
  color: var(--color-navy);
}
.btn--favorite .when-on {
  display: none;
}
.btn--favorite[aria-pressed="true"] .when-on {
  display: inline;
}
.btn--favorite[aria-pressed="true"] .when-off {
  display: none;
}
.session__slides {
  margin-inline: var(--space-3);
  color: var(--color-ink-link);
}
/* ---- Session list ---------------------------------------------------------- */
.filters {
  margin-bottom: var(--space-4);
}
.filters__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  list-style: none;
  cursor: pointer;
}
.filters__summary::-webkit-details-marker {
  display: none;
}
/* Chevron that turns when the panel is open. */
.filters__summary::after {
  content: "";
  width: 0.55rem;
  height: 0.55rem;
  margin-left: var(--space-3);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-20%) rotate(45deg);
  transition: transform var(--transition);
}
.filters[open]>.filters__summary::after {
  transform: translateY(20%) rotate(-135deg);
}
.filters__fields {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}
@media (min-width: 48em) {
  .filters__summary {
    display: none;
  }
  .filters__fields {
    margin-top: 0;
    grid-template-columns: repeat(4, 1fr);
    align-items: end;
  }
  .filters__fields .checkbox {
    grid-column: 1 / -1;
  }
}
.checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.checkbox input {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--color-orange);
}
.btn--light {
  background: var(--color-surface-alt);
  color: var(--color-ink-heading);
}
.btn--light:hover {
  background: color-mix(in srgb, var(--color-surface-alt) 80%, var(--color-ink-heading));
  color: var(--color-ink-heading);
}
.panel .btn--outline {
  border-color: var(--color-muted);
  color: var(--color-ink-heading);
}
.panel .btn--outline:hover {
  background: var(--color-ink-heading);
  color: var(--color-surface);
}
.session-count {
  margin-block: var(--space-3);
  color: var(--color-muted);
  font-weight: var(--weight-bold);
}
/* A light card: a thin outline and a slim track-coloured edge (the track is also named in the card). */
.session {
  margin-bottom: var(--space-2);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--track-color);
  box-shadow: var(--shadow-1);
}
.session__head {
  display: flex;
  align-items: center;
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-2);
}
/* The heading wraps the toggle button, so screen readers get one heading per session. */
.session__heading {
  display: flex;
  flex: 1;
  margin: 0;
  color: inherit;
  font: inherit;
  letter-spacing: 0;
}
.session__toggle {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-1) 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
}
/* Same size as a session in the agenda. */
.session__title {
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0;
}
/* Chevron right behind the session id: points down, turns up while the session is open. */
.session__id::after {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-left: var(--space-2);
  border-right: 2px solid var(--color-muted);
  border-bottom: 2px solid var(--color-muted);
  vertical-align: 0.15em;
  transform: rotate(45deg);
  transition: transform var(--transition);
}
.session__toggle[aria-expanded="true"] .session__id::after {
  vertical-align: -0.1em;
  transform: rotate(-135deg);
}
.session__toggle:hover .session__title {
  text-decoration: underline;
}
.session__track {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-muted);
}
.session__speakers {
  padding: 0 var(--space-3) var(--space-2) var(--space-5);
  font-size: var(--text-sm);
}
.session__body {
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-hairline);
}
.session__body>*+* {
  margin-top: var(--space-2);
}
@media (min-width: 75em) {
  .session__toggle {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-4);
  }
  .session__toggle> :first-child {
    flex: 1;
  }
  .session__toggle>.session__track {
    min-width: 11rem;
  }
}
/* A session as a box (agenda cells, speaker details). */
.session-box {
  padding: var(--space-2);
  font-size: var(--text-sm);
  border-radius: var(--radius-s);
}
.session-box--click {
  cursor: pointer;
}
.session-box--click:hover {
  opacity: 0.9;
}
.session-box__open {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
}
.session-details {
  display: grid;
  gap: var(--space-3);
  border: 0;
  background: none;
}
.session-details__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  color: var(--color-muted);
}
.session-details.preferred {
  background: none;
}
.dialog__subtitle {
  color: var(--color-ink-heading);
  font-size: var(--text-h5);
  font-weight: var(--weight-bold);
}
/* ---- Agenda ---------------------------------------------------------------- */
.schedule__controls {
  display: grid;
  gap: var(--space-3);
  max-width: 60rem;
  margin-bottom: var(--space-4);
}
.schedule__table {
  display: none;
}
@media (min-width: 62em) {
  .schedule__table {
    display: block;
  }
  .schedule__mobile {
    display: none;
  }
}
.schedule-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
}
.schedule-table th,
.schedule-table td {
  min-width: 11rem;
  padding: var(--space-1);
  border: 1px solid var(--color-border);
  vertical-align: top;
}
.schedule-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--color-surface-alt);
  text-align: center;
}
.schedule-table .schedule__time {
  position: sticky;
  left: 0;
  z-index: 1;
  width: 7.5rem;
  min-width: 0;
  background: var(--color-surface-alt);
  font-weight: var(--weight-bold);
}
.schedule-table thead .schedule__time {
  z-index: 3;
}
/* the corner sits above both */
.schedule-table .session-box {
  font-size: var(--text-sm);
}
.schedule-table td .track {
  overflow: hidden;
}
/* "Now" and "Next" (js/sessions.js), on the event day only. */
.schedule__badge {
  display: inline-block;
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-badge);
  color: var(--color-white);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
}
[data-state="now"]>.schedule__time,
.slot[data-state="now"]>.slot__time {
  background: var(--color-orange-tint);
}
[data-state="now"]>.schedule__time .schedule__badge,
[data-state="now"]>.slot__time .schedule__badge {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.slot[data-state="now"] {
  border-color: var(--color-primary);
}
.slot[data-state="next"] {
  border-style: dashed;
}
.slot {
  margin-bottom: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}
.slot__time {
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  font-weight: var(--weight-bold);
}
.slot>.stack {
  display: grid;
  grid-auto-rows: 1fr;
  gap: var(--space-4);
  padding: var(--space-2);
}
.slot>.stack>* {
  margin: 0;
}
/* ---- Speakers --------------------------------------------------------------- */
.speaker-filter {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.speaker-filter__search {
  display: flex;
  gap: var(--space-2);
}
@media (min-width: 62em) {
  .speaker-filter {
    grid-template-columns: 1fr 1fr;
  }
}
/* Cards share the row equally, so the last row has no ragged gap. */
.speaker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11.25rem, 1fr));
  gap: var(--space-4);
}
.speaker-grid>.notice {
  grid-column: 1 / -1;
}
.person-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  background: var(--color-card);
  box-shadow: var(--shadow-1);
  color: var(--color-ink);
  text-align: center;
  transition: transform var(--transition), box-shadow var(--transition);
}
/* Only the clickable card (speaker list) lifts; the board card in the contact dialog is static. */
button.person-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2);
}
@media (min-width: 62em) {
  .speaker-grid {
    grid-template-columns: repeat(auto-fill, minmax(13.125rem, 1fr));
  }
}
.person-card__name {
  display: block;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: 0;
}
.person-card__detail {
  font-size: var(--text-sm);
}
/* A photo with the Ambassador and Penumbra badges in its corners. */
.person-card__photo,
.speaker-details__photo,
.speaker-chip__photo {
  position: relative;
  display: block;
  flex: none;
  width: 9.5rem;
  height: 9.5rem;
}
.person-card__photo {
  width: 8.5rem;
  height: 8.5rem;
}
@media (min-width: 62em) {
  .person-card__photo {
    width: 10.5rem;
    height: 10.5rem;
  }
}
.speaker-chip__photo {
  width: 6rem;
  height: 6rem;
}
.speaker-photo,
.person-card__photo>img:not(.speaker-icon) {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-m);
  background: var(--color-mist);
  object-fit: cover;
}
/* Badges sit on a white disc, so they read on any photo. Each has a title and alt text. */
.speaker-icon {
  position: absolute;
  bottom: 5px;
  width: 2.25rem;
  height: 2.25rem;
  padding: 2px;
  border-radius: var(--radius-m);
  background: var(--color-white);
  box-shadow: var(--shadow-1);
  object-fit: contain;
}
.speaker-icon--ambassador {
  left: 5px;
}
.speaker-icon--penumbra {
  right: 5px;
}
.speaker-chip__photo .speaker-icon {
  width: 1.5rem;
  height: 1.5rem;
}
.speaker-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
.speaker-chip {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
  background: var(--color-card);
  color: var(--color-ink);
  text-align: left;
}
.speaker-chip:hover {
  box-shadow: var(--shadow-2);
}
.speaker-details {
  display: grid;
  gap: var(--space-4);
}
@media (min-width: 48em) {
  .speaker-details {
    grid-template-columns: auto 1fr;
    align-items: start;
  }
}
.speaker-details__photo {
  width: 10rem;
  height: 10rem;
}
.speaker-rank {
  font-weight: var(--weight-bold);
}
.speaker-rank--1 {
  color: var(--color-ambassador);
}
.speaker-rank--2 {
  color: var(--color-lifetime);
}
/* ---- Info pages (Attend, About, Speak) -------------------------------------- */
.page-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-1) var(--space-4);
}
.page-links .btn {
  color: var(--color-heading);
}
.grid--features {
  --min: 20rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.grid--features>* {
  flex: 0 1 var(--min);
}
.cluster--center {
  justify-content: center;
}
.stack>.cluster--center+*,
.stack>*+.cluster--center {
  margin-top: var(--space-4);
}
.bullets {
  padding-left: var(--space-5);
  list-style: disc;
}
.bullets li+li {
  margin-top: var(--space-1);
}
.form-actions {
  display: flex;
  justify-content: flex-end;
}
/* A group of related fields in a long form (the Sponsor form). */
.form-group {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-m);
}
.form-group>legend {
  padding-inline: var(--space-2);
  color: var(--color-ink-heading);
  font-weight: var(--weight-bold);
}
.form-group>*+* {
  margin-top: var(--space-3);
}
/* ---- Sponsor page ------------------------------------------------------------- */
/* A wide table scrolls sideways inside its own box instead of widening the page.
   position: relative keeps the .visually-hidden texts in the table inside that box too. */
.table-scroll {
  position: relative;
  overflow-x: auto;
}
/* The package comparison: one row per benefit, one column per tier. The first
   column stays in view while the table scrolls. */
.packages {
  width: 100%;
  min-width: 44rem;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.packages th,
.packages td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: center;
  vertical-align: middle;
}
.packages tbody th,
.packages__fee th {
  font-weight: var(--weight-body);
  text-align: left;
}
.packages thead th {
  background: var(--color-surface-alt);
  color: var(--color-ink-heading);
}
.packages tbody tr:not(.packages__section)>th {
  position: sticky;
  left: 0;
  background: var(--color-surface);
}
/* The tier name as a chip in the tier colour (as on the sponsors page). */
.packages__tier {
  display: inline-block;
  padding: 0 var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--tier-color, var(--color-border));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-navy) 25%, transparent);
  color: var(--color-navy);
  font-weight: var(--weight-bold);
}
.packages__fee>* {
  background: var(--color-surface-alt);
  vertical-align: top;
}
.packages .packages__section th {
  background: var(--color-badge);
  color: var(--color-white);
  font-weight: var(--weight-bold);
  text-align: left;
}
.packages .fa-check {
  color: var(--color-accent-text);
}
.packages__subtitle {
  margin-block: var(--space-6) var(--space-3);
  font-size: var(--text-h4);
}
.packages--options {
  min-width: 30rem;
}
.packages--options td {
  text-align: right;
  white-space: nowrap;
}
.packages__soldout {
  color: var(--color-danger);
  font-weight: var(--weight-bold);
}
/* The small info icon that explains a row. */
.tip {
  cursor: help;
  color: var(--color-accent-text);
}
/* In the table the bubble starts at the icon and runs to the right, so the scroll box doesn't cut it off on the left. */
.packages [data-tip]::after {
  left: 0;
  transform: none;
  text-align: left;
}
/* A colour sample (banner colours): the colour is set on the cell with --swatch. */
.swatch {
  background: var(--swatch);
  box-shadow: inset 0 0 0 1px var(--color-border);
  color: var(--color-white);
}
.swatch--light {
  color: var(--color-navy);
}
address {
  font-style: normal;
}
/* Decorative images that only take space: shown from md up. */
.hide-small {
  display: none;
}
@media (min-width: 48em) {
  .hide-small {
    display: block;
  }
}
/* ---- Dialog content ------------------------------------------------------------
   The dialogs (Venue, Travel, Sponsor, ...) show pieces of HTML written in the
   Domino database. They use these small building blocks, inside .dialog__body. */
.text-accent {
  color: var(--color-ink-link);
}
.text-success {
  color: var(--color-success);
}
.rounded {
  border-radius: var(--radius-m);
}
.shadow {
  box-shadow: var(--shadow-1);
}
.span-all {
  grid-column: 1 / -1;
}
.dialog__body .grid {
  --min: 15rem;
  --space: var(--space-4);
  /* auto-fit: no empty tracks, so the cards use the full dialog width */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr));
}
/* Grids stacked inside a wrapper div (not direct children of the body) get the same gap as the grid rows. */
.dialog__body .grid+.grid {
  margin-top: var(--space-4);
}
/* Text/image rows: text gets 2/3, image 1/3 from sm up; stacked below. */
@media (min-width: 40em) {
  .dialog__body .grid--text-image {
    grid-template-columns: 2fr 1fr;
  }
  .dialog__body .grid--image-text {
    grid-template-columns: 1fr 2fr;
  }
  /* Two equal columns; one column below sm. */
  .dialog__body .grid--2,
  .dialog__body .grid--4 {
    grid-template-columns: repeat(2, 1fr);
  }
}
/* Four equal columns from lg up (two from sm, see above). */
@media (min-width: 62em) {
  .dialog__body .grid--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}
/* A caption under a picture. */
.dialog__body .grid--4 img+p {
  margin-top: var(--space-3);
}
.dialog__body>*+*,
.dialog__body>[data-title]>*+* {
  margin-top: var(--space-4);
}
.dialog__body h4 {
  color: var(--color-ink-heading);
}
.dialog__body ul:not([class]) {
  padding-left: var(--space-5);
  list-style: disc;
}
.dialog__body li+li {
  margin-top: var(--space-1);
}
.dialog__body img {
  border-radius: var(--radius-m);
}
/* Icon next to a heading and text. */
.fact {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}
.fact>div>*+* {
  margin-top: var(--space-1);
}
.fact h5 {
  color: var(--color-ink-heading);
  font-weight: var(--weight-bold);
}
.fact__icon {
  flex: none;
  width: 1.75rem;
  text-align: center;
}
/* A box with a light edge. */
.tile {
  padding: var(--space-4);
  border-radius: var(--radius-m);
  background: var(--color-card);
  box-shadow: var(--shadow-1);
}
.tile h4 {
  margin-bottom: var(--space-2);
}
/* Tiles in a grid row share the row height. The wrapper div stretches; the tile fills it. */
.grid>*>.tile {
  height: 100%;
}
/* Space between the icon and the title. */
.tile h4>i {
  margin-right: var(--space-2);
}
/* Board members: person cards in a row, with a smaller photo than the speaker grid. */
.people {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-4);
}
.people>.person-card {
  flex: 0 1 12rem;
}
.people .person-card__photo {
  width: 8.5rem;
  height: 8.5rem;
}
/* Sponsor details: logo, links and text. */
.sponsor-details {
  display: grid;
  gap: var(--space-4);
}
.sponsor-details__logo {
  align-self: center;
  padding: var(--space-3);
  border-radius: var(--radius-m);
  background: var(--color-white);
  box-shadow: var(--shadow-1);
}
.sponsor-details__logo img {
  width: 100%;
  border-radius: 0;
}
.sponsor-details__links .penumbra {
  display: inline-block;
  width: 1.875rem;
  margin-top: var(--space-2);
}
.sponsor-details__text {
  grid-column: 1 / -1;
}
@media (min-width: 40em) {
  .sponsor-details {
    grid-template-columns: 1fr 2fr;
  }
}
