/* ===============================================================
   Shared chrome
   =============================================================== */

.marquee {
  overflow: hidden;
  border-block: var(--sk-stroke) solid var(--sk-fluid);
  background: var(--sk-bg);
  margin-top: var(--sk-frame);
}
.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee-scroll 32s linear infinite;
}
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}
.marquee__item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 40px;
  font-size: var(--sk-fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  text-decoration: none;
  white-space: nowrap;
}
.marquee__item::after {
  content: "";
  width: 6px; height: 6px;
  background: var(--sk-fluid);
  border-radius: 50%;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sk-gap);
  padding-block: 28px;
  border-bottom: var(--sk-stroke) solid var(--sk-ink);
}
.site-nav__brand {
  font-weight: 700;
  font-size: var(--sk-fs-lg);
  letter-spacing: -0.02em;
  text-decoration: none;
}
.site-nav__links { display: flex; flex-wrap: wrap; gap: 28px; }
.site-nav__link {
  font-size: var(--sk-fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 2px solid transparent;
}
.site-nav__link:hover { border-bottom-color: var(--sk-ink); }
.site-nav__link.is-active { border-bottom-color: var(--sk-fluid); }

.site-footer {
  margin-top: 120px;
  padding-block: 56px 72px;
  border-top: var(--sk-stroke) solid var(--sk-ink);
}
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sk-gap);
  justify-content: space-between;
  align-items: flex-start;
}
.site-footer__links { display: flex; flex-wrap: wrap; gap: 24px; }
.site-footer__link {
  font-size: var(--sk-fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
.site-footer__link:hover { border-bottom-color: var(--sk-fluid); }

.page-head { padding-block: clamp(64px, 9vw, 120px) 48px; }
.page-head h1 { max-width: 20ch; }
.page-head p { max-width: 62ch; margin-top: 20px; }

.section__head { margin-bottom: clamp(48px, 7vw, 96px); }
.section__head h2 { font-size: clamp(28px, 4vw, 46px); font-weight: 700; letter-spacing: -0.02em; }
.section__head p { max-width: 60ch; margin-top: 16px; }

/* ===============================================================
   Landing
   =============================================================== */

.hero { padding-block: clamp(72px, 11vw, 168px) clamp(80px, 12vw, 180px); }
.hero__eyebrow { color: var(--sk-fluid); }
.hero__title { margin-block: 24px 28px; }
.hero__lede { max-width: 54ch; font-size: clamp(16px, 1.6vw, 20px); }
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  margin-top: 72px;
}
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 40px;
  margin-top: 88px;
  padding-top: 28px;
  border-top: var(--sk-stroke) solid var(--sk-ink);
}
.hero__meta div { min-width: 140px; }
.hero__meta dt { font-size: 11px; text-transform: uppercase; letter-spacing: 0.16em; opacity: 0.6; }
.hero__meta dd { font-size: var(--sk-fs-lg); font-weight: 700; margin-top: 6px; }

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 56px;
}
.team-card {
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 220px;
}
.team-card__name { font-size: var(--sk-fs-lg); font-weight: 700; letter-spacing: -0.01em; }
.team-card__role { font-size: var(--sk-fs-sm); opacity: 0.7; }
.team-card__program { margin-top: auto; }
.team-card__links { display: flex; gap: 18px; flex-wrap: wrap; }
.team-card__links a {
  font-size: var(--sk-fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border-bottom: 2px solid var(--sk-ink);
  text-decoration: none;
  padding-bottom: 2px;
}
.team-card__links a:hover { border-bottom-color: var(--sk-fluid); color: var(--sk-fluid); }

.faq-list { border-top: var(--sk-stroke) solid var(--sk-ink); max-width: 900px; }
.faq-item { border-bottom: var(--sk-stroke) solid var(--sk-ink); }
.faq-item__q {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  align-items: baseline;
  padding: 26px 0;
  font-size: clamp(17px, 2vw, 21px);
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.faq-item__q::-webkit-details-marker { display: none; }
.faq-item__q::after { content: "+"; font-weight: 400; color: var(--sk-fluid); font-size: 26px; line-height: 1; }
.faq-item[open] .faq-item__q::after { content: "\2212"; }
.faq-item__a { padding-bottom: 28px; max-width: 66ch; }

/* ===============================================================
   Schedule — vertical gantt
   =============================================================== */

.gantt {
  display: grid;
  grid-template-columns: 104px repeat(3, minmax(0, 1fr)) 150px;
  gap: 28px;
  position: relative;
}
.gantt__head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding-bottom: 14px;
  border-bottom: var(--sk-stroke) solid var(--sk-ink);
  margin-bottom: 18px;
}
.gantt__col { position: relative; }

.gantt__axis { position: relative; }
.gantt__tick {
  position: absolute;
  left: 0;
  right: 0;
  font-size: 11px;
  letter-spacing: 0.08em;
  opacity: 0.65;
  border-top: 1px dashed currentColor;
  padding-top: 4px;
}
.gantt__phase {
  position: absolute;
  left: 56px;
  right: 0;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: 6px;
  background: var(--sk-fill);
  display: flex;
  align-items: flex-start;
  padding: 8px 6px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  writing-mode: vertical-rl;
}
.gantt__phase--alt { background: var(--sk-fluid); color: var(--sk-bg); border-color: var(--sk-fluid); }

/* Right axis: real wall-clock date/time, in contrast to the left axis's
   elapsed-hour ticks. A slim warning-coloured rule marks each late-night
   window (12am–6am); tick text is padded clear of it so the rule reads as a
   flag rather than colliding with the label. */
.gantt__tick--date { padding-left: 16px; }
.gantt__night {
  position: absolute;
  left: 0;
  width: 6px;
  border-radius: 3px;
  background: var(--sk-warn);
}

/* A short phase has little band to run its label along. Tighter type buys
   the room back; the ellipsis below is the last resort for a label no
   amount of tightening will fit, so it can never cut a glyph in half. */
.gantt__phase--tight { padding: 3px 4px; }
.gantt__phase--tight span { font-size: 9px; letter-spacing: 0.02em; }
.gantt__phase span {
  display: block;
  max-height: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.gantt__lane { position: relative; border-left: 1px dashed rgba(0, 0, 0, 0.35); }
.gantt__block {
  position: absolute;
  left: 10px;
  right: 0;
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
  padding: 14px 16px;
  overflow: hidden;
  text-decoration: none;
  display: block;
}
a.gantt__block { border-color: var(--sk-fluid); }
a.gantt__block:hover { background: var(--sk-fluid); color: var(--sk-bg); }
.gantt__block strong { display: block; font-size: var(--sk-fs-sm); line-height: 1.3; }
.gantt__block span { font-size: 11px; opacity: 0.7; letter-spacing: 0.08em; }
.gantt__block--compact {
  padding: 8px 16px;
  display: flex;
  align-items: center;
}
.gantt__block--compact strong { font-size: 12px; }

.workshop-list { display: grid; gap: 28px; max-width: 900px; }
.workshop-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding: 26px 28px;
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
  text-decoration: none;
}
.workshop-row:hover { border-color: var(--sk-fluid); color: var(--sk-fluid); }
.workshop-row__title { font-size: var(--sk-fs-lg); font-weight: 700; letter-spacing: -0.01em; }
.workshop-row__meta { font-size: var(--sk-fs-sm); opacity: 0.75; }

/* ===============================================================
   Workshop detail
   =============================================================== */

.workshop-detail { display: grid; gap: 56px; max-width: 820px; }
.workshop-detail__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 36px;
  padding: 28px 32px;
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
}
.workshop-detail__meta dt { font-size: 11px; text-transform: uppercase; letter-spacing: 0.16em; opacity: 0.6; }
.workshop-detail__meta dd { font-weight: 700; margin-top: 5px; }
.workshop-detail h2 { font-size: var(--sk-fs-lg); margin-bottom: 14px; }
.workshop-detail li { padding-left: 22px; position: relative; margin-bottom: 8px; }
.workshop-detail li::before { content: "\2014"; position: absolute; left: 0; color: var(--sk-fluid); }

/* ===============================================================
   Past events
   =============================================================== */

.event-feature {
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius-lg);
  padding: clamp(32px, 5vw, 64px);
  display: grid;
  gap: 32px;
}
.event-feature__head { display: flex; flex-wrap: wrap; gap: 20px; align-items: baseline; justify-content: space-between; }
.event-feature__title { font-size: clamp(26px, 3.4vw, 40px); font-weight: 700; letter-spacing: -0.02em; }
.event-feature__summary { max-width: 62ch; }
.event-feature li { padding-left: 26px; position: relative; margin-bottom: 10px; }
.event-feature li::before { content: "\2713"; position: absolute; left: 0; color: var(--sk-fluid); }

/* Same reasoning as .filters: leaves room for a dimension escalated to an
   outer lane so it can't land on the next row's heading. */
.event-list { display: grid; gap: 140px; max-width: 900px; }
.event-row {
  display: grid;
  gap: 10px;
  padding: 28px 32px;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
}
.event-row__head { display: flex; flex-wrap: wrap; gap: 16px; align-items: baseline; justify-content: space-between; }
.event-row__title { font-size: var(--sk-fs-lg); font-weight: 700; }
.event-row__meta { font-size: var(--sk-fs-sm); opacity: 0.7; }

/* ===============================================================
   Components
   =============================================================== */

/* Generous gaps: the annotated chip's radius leader and height dimension
   need clear space between the two rows. */
/* Rows stack close enough that a dimension pushed to an outer lane (up to
   baseGap + 3*laneStep + label height, ~140px worst case) can reach the row
   below it — this gap has to clear that, not just look tidy. */
.filters { display: grid; gap: 140px; margin-bottom: 96px; }
/* Row-gap and column-gap are set separately: chips can stay tight
   horizontally, but if the row wraps (enough chips to need a second line),
   that line needs the same ~140px clearance as any other stacked group, or
   a wrapped chip lands directly in the representative chip's own dimension
   line, which sits below it. */
.filters__row { display: flex; flex-wrap: wrap; gap: 140px 12px; align-items: center; }
.filters__label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  opacity: 0.6;
  min-width: 74px;
}

.filters__chips { display: flex; flex-wrap: wrap; gap: 140px 12px; align-items: center; }

/* The type row has enough chips to wrap on its own, but left alone it breaks
   7-then-1 — one lonely chip on a mostly empty second line. Capping the chip
   block forces an even split, and the plate then occupies the whole void
   beside it rather than a single line's leftover. */
.filters__row[data-filter-row="type"] { align-items: stretch; gap: 12px 56px; }
/* Sized to hug the wider of the two wrapped lines (~600px) while still
   fitting four chips on the first — anything larger just pads the block with
   slack the plate could be using. */
.filters__row[data-filter-row="type"] .filters__chips { max-width: 620px; }

/* The plate exists to fill the void beside the chips, and that void only
   exists once the row is wide enough to leave one. Narrower than that the
   chips reflow across the full width, and the plate would wrap onto its own
   flex line — collapsing to a zero-height sliver, since its only children are
   absolutely positioned. Below the annotation breakpoint it simply goes away. */
.filters__plate { display: none; }

/* 1210px is measured, not estimated: it's the first width at which the label,
   the capped chip block, the gaps and the plate's 260px minimum all fit on one
   line. At 1200 the plate wraps underneath the chips, which is not the thing
   it's for, so below this it doesn't render at all. */
@media (min-width: 1210px) {
  .filters__plate {
    display: block;
    position: relative;
    flex: 1 1 0;
    min-width: 260px;
    min-height: 150px;
    align-self: stretch;
  }
}
.filters__plate.sk { border-radius: 8px; }

/* Holes are real elements so the annotation engine measures them like any
   other feature. Percentage positions keep them located relative to the
   plate, so their dimensions stay live as it resizes. */
.plate__hole {
  position: absolute;
  border: var(--sk-stroke) solid var(--sk-fluid);
  border-radius: 50%;
  background: var(--sk-bg);
  transform: translate(-50%, -50%);
}
.plate__hole--lg {
  width: 46px;
  height: 46px;
  /* Far enough in that its radius leader, which exits up-left, lands inside
     the plate instead of running off the edge. */
  left: 32%;
  top: 50%;
}
.plate__pattern {
  position: absolute;
  right: 9%;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 30px;
}
.plate__pattern .plate__hole {
  position: relative;
  width: 22px;
  height: 22px;
  transform: none;
}
.chip {
  padding: 8px 18px;
  background: transparent;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: 999px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--sk-ink); color: var(--sk-bg); }
.chip:hover { border-color: var(--sk-fluid); }

.scope-group { margin-bottom: 96px; }
.scope-group__head {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 16px;
  border-bottom: var(--sk-stroke) solid var(--sk-ink);
  margin-bottom: 40px;
}
.scope-group__title { font-size: clamp(22px, 3vw, 32px); font-weight: 700; letter-spacing: -0.02em; }
/* Leaves room for the representative card's dimensions to sit below it
   without running into the next group's heading. */
/* Worst-case lane escalation for the representative card's width dimension
   can reach ~140px below it, past the smaller gap this used to be. */
.type-group { margin-bottom: 140px; }
.type-group__title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  opacity: 0.6;
  margin-bottom: 30px;
}
.component-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 24px;
}
.component-card {
  position: relative;
  background: var(--sk-fill);
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: var(--sk-radius);
  padding: 22px 24px;
  display: grid;
  gap: 8px;
  align-content: start;
  min-height: 130px;
}
/* Leaves the top-right corner clear for the upgrade mark. */
.component-card__name { font-weight: 700; padding-right: 34px; }

/* Upgrade mark: a CAD balloon callout in the card's top-right corner. Kept in
   --sk-ink rather than colour-coded per upgrade, because on this site colour
   already means something specific (black is fixed geometry, blue is
   viewport-dependent) and a third meaning would muddy it. The letter carries
   the distinction. */
.component-card__upgrade {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: 50%;
  background: var(--sk-bg);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}

.upgrade-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin-top: 28px;
  font-size: var(--sk-fs-sm);
}
.upgrade-legend li { display: flex; align-items: center; gap: 10px; }
.upgrade-legend__mark {
  width: 24px;
  height: 24px;
  flex: none;
  display: grid;
  place-items: center;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: 50%;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}
.component-card__qty { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--sk-fluid); }
.component-card__notes { font-size: var(--sk-fs-sm); opacity: 0.7; }
.is-empty { opacity: 0.6; font-size: var(--sk-fs-sm); }

/* ===============================================================
   Sponsorship prospectus
   =============================================================== */

/* Stat tiles reused outside the hero, where there's no top border to hang
   off of. */
.hero__meta--flush { margin-top: 0; padding-top: 0; border-top: none; }

.why-list { display: grid; gap: 18px; max-width: 66ch; }
.why-list li { padding-left: 26px; position: relative; }
.why-list li::before { content: "\2713"; position: absolute; left: 0; color: var(--sk-fluid); }

.benefit-table-wrap {
  /* A 5-column comparison table doesn't reflow onto a phone screen the way
     prose does — it scrolls in its own box rather than forcing the page
     wider than the viewport. `overflow-x: auto` alone isn't sufficient: a
     table's intrinsic min-width can still leak past it and inflate
     documentElement.scrollWidth, scrolling the whole page horizontally
     even though the wrapper itself measures as properly contained.
     `contain: paint` forces a real containing block regardless. */
  overflow-x: auto;
  contain: paint;
}
.benefit-table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  table-layout: fixed;
}
.benefit-table th, .benefit-table td {
  border: var(--sk-stroke) solid var(--sk-ink);
  padding: 14px 16px;
}
.benefit-table__corner { border: none; }
.benefit-table th:first-child, .benefit-table td:first-child { width: 34%; text-align: left; }

.tier-head {
  background: var(--sk-fill);
  text-align: center;
  vertical-align: top;
}
.tier-head__name {
  display: block;
  font-size: var(--sk-fs-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.tier-head__price {
  display: block;
  margin-top: 6px;
  font-size: var(--sk-fs-lg);
  font-weight: 700;
  color: var(--sk-fluid);
}

.benefit-table__label { font-weight: 600; text-align: left; }
.benefit-table tbody tr:nth-child(even) { background: var(--sk-fill); }
.benefit-table td:not(:first-child) { text-align: center; }

/* Checkbox grid: an empty square is "not included," a filled square with a
   check is "included" — drawn with a pseudo-element so the markup only has
   to say which state applies, not which glyph represents it. */
.benefit-table__check {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: var(--sk-stroke) solid var(--sk-ink);
  border-radius: 4px;
  position: relative;
  vertical-align: middle;
}
.benefit-table__check.is-included { background: var(--sk-ink); }
.benefit-table__check.is-included::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 42%;
  width: 5px;
  height: 9px;
  border: solid var(--sk-bg);
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -50%) rotate(45deg);
}

/* A benefit that differs by degree rather than presence — "mention" vs.
   "keynote" — reads as a small tag, not a checkbox, so it's never mistaken
   for a plain yes/no. */
.benefit-table__value {
  display: inline-block;
  padding: 4px 10px;
  border: 1px solid var(--sk-fluid);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: capitalize;
  letter-spacing: 0.04em;
  color: var(--sk-fluid);
}

.sponsor-contact { display: grid; gap: 32px; max-width: 66ch; }

@media (max-width: 760px) {
  /* The date/time column is supplementary at this width — the block labels
     already carry hour spans. Dropping its track (not just hiding its
     content) keeps it from reserving a blank 150px column. */
  .gantt { grid-template-columns: 72px repeat(3, minmax(0, 1fr)); gap: 12px; }
  .gantt__phase { left: 34px; }
  .gantt__axis--dates, .gantt__head--dates { display: none; }
  .team-grid { gap: 32px; }
  .hero__actions { gap: 24px; }
}
